1use crate::{
2 archetype::{
3 Archetype, ArchetypeColumnInfo, ArchetypeDynamicEntityColumnAccess,
4 ArchetypeEntityColumnAccess, ArchetypeEntityRowAccess, ArchetypeError,
5 },
6 bundle::{Bundle, BundleColumns},
7 entity::Entity,
8 processor::{WorldProcessor, WorldProcessorEntityMapping},
9 query::{
10 DynamicLookupAccess, DynamicLookupIter, DynamicQueryFilter, DynamicQueryIter,
11 TypedLookupAccess, TypedLookupFetch, TypedLookupIter, TypedQueryFetch, TypedQueryIter,
12 },
13 Component, ComponentRef, ComponentRefMut,
14};
15use intuicio_core::{registry::Registry, types::struct_type::NativeStructBuilder};
16use intuicio_data::type_hash::TypeHash;
17use std::{
18 collections::{HashMap, HashSet, VecDeque},
19 error::Error,
20 marker::PhantomData,
21 sync::{Arc, RwLock, RwLockReadGuard},
22};
23
24#[derive(Debug, PartialEq, Eq)]
25pub enum WorldError {
26 Archetype(ArchetypeError),
27 ReachedEntityIdCapacity,
28 ReachedArchetypeIdCapacity,
29 EntityDoesNotExists { entity: Entity },
30 ArchetypeDoesNotExists { id: u32 },
31 DuplicateMutableArchetypeAccess { id: u32 },
32 EmptyColumnSet,
33}
34
35impl WorldError {
36 pub fn allow<T>(
37 input: Result<T, Self>,
38 items: impl IntoIterator<Item = Self>,
39 ok: T,
40 ) -> Result<T, Self> {
41 match input {
42 Err(error) => {
43 if items.into_iter().any(|item| error == item) {
44 Ok(ok)
45 } else {
46 Err(error)
47 }
48 }
49 result => result,
50 }
51 }
52}
53
54impl Error for WorldError {}
55
56impl From<ArchetypeError> for WorldError {
57 fn from(value: ArchetypeError) -> Self {
58 Self::Archetype(value)
59 }
60}
61
62impl std::fmt::Display for WorldError {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 match self {
65 Self::Archetype(archetype) => write!(f, "World archetype: {}", archetype),
66 Self::ReachedEntityIdCapacity => write!(f, "Reached entity id capacity"),
67 Self::ReachedArchetypeIdCapacity => write!(f, "Reached archetype id capacity"),
68 Self::EntityDoesNotExists { entity } => {
69 write!(f, "Entity does not exists: {}", entity)
70 }
71 Self::ArchetypeDoesNotExists { id } => {
72 write!(f, "Archetype does not exists: {}", id)
73 }
74 Self::DuplicateMutableArchetypeAccess { id } => {
75 write!(f, "Trying to access mutably same archetype twice: {}", id)
76 }
77 Self::EmptyColumnSet => {
78 write!(f, "Trying to perform change on empty column set")
79 }
80 }
81 }
82}
83
84#[derive(Default)]
85struct EntityMap {
86 id_generator: u32,
87 table: Vec<(u32, Option<u32>)>,
89 reusable: Vec<Entity>,
90 size: usize,
91}
92
93impl EntityMap {
94 fn is_empty(&self) -> bool {
95 self.size == 0
96 }
97
98 fn len(&self) -> usize {
99 self.size
100 }
101
102 fn iter(&self) -> impl Iterator<Item = Entity> + '_ {
103 self.table
104 .iter()
105 .enumerate()
106 .filter_map(|(id, (generation, archetype))| {
107 if archetype.is_some() {
108 Some(unsafe { Entity::new_unchecked(id as u32, *generation) })
109 } else {
110 None
111 }
112 })
113 }
114
115 fn clear(&mut self) {
116 self.id_generator = 0;
117 self.table.clear();
118 self.reusable.clear();
119 self.size = 0;
120 }
121
122 fn acquire(&mut self) -> Result<(Entity, &mut Option<u32>), WorldError> {
123 if let Some(mut entity) = self.reusable.pop() {
124 let (generation, archetype) = &mut self.table[entity.id() as usize];
125 entity = entity.bump_generation();
126 *generation = entity.generation();
127 self.size += 1;
128 return Ok((entity, archetype));
129 }
130 if self.id_generator == u32::MAX {
131 Err(WorldError::ReachedEntityIdCapacity)
132 } else {
133 let id = self.id_generator;
134 self.id_generator += 1;
135 while self.table.len() < self.id_generator as usize {
136 if self.table.len() == self.table.capacity() {
137 self.table.reserve_exact(self.table.capacity());
138 }
139 self.table.push((0, None));
140 }
141 let (_, archetype) = &mut self.table[id as usize];
142 self.size += 1;
143 Ok((Entity::new(id, 0).unwrap(), archetype))
144 }
145 }
146
147 fn release(&mut self, entity: Entity) -> Result<u32, WorldError> {
148 if let Some((generation, archetype)) = self.table.get_mut(entity.id() as usize) {
149 if entity.generation() == *generation {
150 if let Some(archetype) = archetype.take() {
151 self.reusable.push(entity);
152 self.size -= 1;
153 Ok(archetype)
154 } else {
155 Err(WorldError::EntityDoesNotExists { entity })
156 }
157 } else {
158 Err(WorldError::EntityDoesNotExists { entity })
159 }
160 } else {
161 Err(WorldError::EntityDoesNotExists { entity })
162 }
163 }
164
165 fn get(&self, entity: Entity) -> Result<u32, WorldError> {
166 if let Some((generation, archetype)) = self.table.get(entity.id() as usize) {
167 if entity.generation() == *generation {
168 if let Some(archetype) = *archetype {
169 Ok(archetype)
170 } else {
171 Err(WorldError::EntityDoesNotExists { entity })
172 }
173 } else {
174 Err(WorldError::EntityDoesNotExists { entity })
175 }
176 } else {
177 Err(WorldError::EntityDoesNotExists { entity })
178 }
179 }
180
181 fn set(&mut self, entity: Entity, archetype_id: u32) -> Result<(), WorldError> {
182 if let Some((generation, archetype)) = self.table.get_mut(entity.id() as usize) {
183 if entity.generation() == *generation {
184 if let Some(archetype) = archetype.as_mut() {
185 *archetype = archetype_id;
186 Ok(())
187 } else {
188 Err(WorldError::EntityDoesNotExists { entity })
189 }
190 } else {
191 Err(WorldError::EntityDoesNotExists { entity })
192 }
193 } else {
194 Err(WorldError::EntityDoesNotExists { entity })
195 }
196 }
197}
198
199#[derive(Default)]
200struct ArchetypeMap {
201 id_generator: u32,
202 table: Vec<Option<Archetype>>,
204 reusable: Vec<u32>,
205}
206
207impl ArchetypeMap {
208 fn iter(&self) -> impl Iterator<Item = &Archetype> + '_ {
209 self.table.iter().filter_map(|archetype| archetype.as_ref())
210 }
211
212 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Archetype> + '_ {
213 self.table
214 .iter_mut()
215 .filter_map(|archetype| archetype.as_mut())
216 }
217
218 fn clear(&mut self) {
219 self.id_generator = 0;
220 self.table.clear();
221 self.reusable.clear();
222 }
223
224 fn acquire(&mut self) -> Result<(u32, &mut Option<Archetype>), WorldError> {
225 if let Some(id) = self.reusable.pop() {
226 let archetype = &mut self.table[id as usize];
227 return Ok((id, archetype));
228 }
229 if self.id_generator == u32::MAX {
230 Err(WorldError::ReachedArchetypeIdCapacity)
231 } else {
232 let id = self.id_generator;
233 self.id_generator += 1;
234 while self.table.len() < self.id_generator as usize {
235 if self.table.len() == self.table.capacity() {
236 self.table.reserve_exact(self.table.capacity());
237 }
238 self.table.push(None);
239 }
240 let archetype = &mut self.table[id as usize];
241 Ok((id, archetype))
242 }
243 }
244
245 fn get(&self, id: u32) -> Result<&Archetype, WorldError> {
246 if let Some(archetype) = self
247 .table
248 .get(id as usize)
249 .and_then(|archetype| archetype.as_ref())
250 {
251 Ok(archetype)
252 } else {
253 Err(WorldError::ArchetypeDoesNotExists { id })
254 }
255 }
256
257 fn get_mut(&mut self, id: u32) -> Result<&mut Archetype, WorldError> {
258 if let Some(archetype) = self
259 .table
260 .get_mut(id as usize)
261 .and_then(|archetype| archetype.as_mut())
262 {
263 Ok(archetype)
264 } else {
265 Err(WorldError::ArchetypeDoesNotExists { id })
266 }
267 }
268
269 fn get_mut_two(&mut self, [a, b]: [u32; 2]) -> Result<[&mut Archetype; 2], WorldError> {
270 if a == b {
271 return Err(WorldError::DuplicateMutableArchetypeAccess { id: a });
272 }
273 if let Some(archetype) = self.table.get(a as usize) {
274 if archetype.is_none() {
275 return Err(WorldError::ArchetypeDoesNotExists { id: a });
276 }
277 } else {
278 return Err(WorldError::ArchetypeDoesNotExists { id: a });
279 }
280 if let Some(archetype) = self.table.get(b as usize) {
281 if archetype.is_none() {
282 return Err(WorldError::ArchetypeDoesNotExists { id: b });
283 }
284 } else {
285 return Err(WorldError::ArchetypeDoesNotExists { id: b });
286 }
287 if a < b {
288 let (left, right) = self.table.split_at_mut(b as usize);
289 Ok([
290 left[a as usize].as_mut().unwrap(),
291 right[0].as_mut().unwrap(),
292 ])
293 } else {
294 let (right, left) = self.table.split_at_mut(a as usize);
295 Ok([
296 left[0].as_mut().unwrap(),
297 right[b as usize].as_mut().unwrap(),
298 ])
299 }
300 }
301
302 fn find_by_columns_exact(&self, columns: &[ArchetypeColumnInfo]) -> Option<u32> {
303 for (id, archetype) in self.table.iter().enumerate() {
304 if let Some(archetype) = archetype.as_ref() {
305 if archetype.has_columns_exact(columns) {
306 return Some(id as u32);
307 }
308 }
309 }
310 None
311 }
312}
313
314#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
315enum RelationConnections<T: Component> {
316 Zero([(T, Entity); 0]),
317 One([(T, Entity); 1]),
318 More(Vec<(T, Entity)>),
319}
320
321impl<T: Component> Default for RelationConnections<T> {
322 fn default() -> Self {
323 Self::Zero(Default::default())
324 }
325}
326
327#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
328pub struct Relation<T: Component> {
329 connections: RelationConnections<T>,
330}
331
332impl<T: Component> Default for Relation<T> {
333 fn default() -> Self {
334 Self {
335 connections: Default::default(),
336 }
337 }
338}
339
340impl<T: Component> Relation<T> {
341 pub fn install_to_registry(registry: &mut Registry) {
342 registry.add_type(NativeStructBuilder::new::<Self>().build());
343 }
344
345 pub fn register_to_processor(processor: &mut WorldProcessor) {
346 processor.register_entity_remapping::<Self>(|relation, mapping| {
347 let iter = match &mut relation.connections {
348 RelationConnections::Zero(a) => a.iter_mut(),
349 RelationConnections::One(a) => a.iter_mut(),
350 RelationConnections::More(vec) => vec.iter_mut(),
351 };
352 for (_, entity) in iter {
353 *entity = mapping.remap(*entity);
354 }
355 });
356 processor.register_entity_inspector::<Self>(|relation| {
357 relation.iter().map(|(_, entity)| entity).collect()
358 });
359 processor.register_formatter::<Self>(|relation, fmt| {
360 fmt.debug_struct("Relation")
361 .field(
362 "entities",
363 &relation
364 .iter()
365 .map(|(_, entity)| entity)
366 .collect::<Vec<_>>(),
367 )
368 .finish_non_exhaustive()
369 });
370 }
371
372 pub fn register_to_processor_debug(processor: &mut WorldProcessor)
373 where
374 T: std::fmt::Debug,
375 {
376 processor.register_debug_formatter::<Self>();
377 }
378
379 pub fn new(payload: T, entity: Entity) -> Self {
380 Self::default().with(payload, entity)
381 }
382
383 pub fn with(mut self, payload: T, entity: Entity) -> Self {
384 self.add(payload, entity);
385 self
386 }
387
388 pub fn type_hash(&self) -> TypeHash {
389 TypeHash::of::<T>()
390 }
391
392 pub fn is_empty(&self) -> bool {
393 match &self.connections {
394 RelationConnections::Zero(_) => true,
395 RelationConnections::One(_) => false,
396 RelationConnections::More(vec) => vec.is_empty(),
397 }
398 }
399
400 pub fn add(&mut self, payload: T, entity: Entity) {
401 self.connections = match std::mem::take(&mut self.connections) {
402 RelationConnections::Zero(_) => RelationConnections::One([(payload, entity)]),
403 RelationConnections::One([a]) => RelationConnections::More(vec![a, (payload, entity)]),
404 RelationConnections::More(mut vec) => {
405 if let Some(index) = vec.iter().position(|item| item.1 == entity) {
406 vec[index].0 = payload;
407 } else {
408 vec.push((payload, entity));
409 }
410 RelationConnections::More(vec)
411 }
412 };
413 }
414
415 pub fn remove(&mut self, entity: Entity) {
416 self.connections = match std::mem::take(&mut self.connections) {
417 RelationConnections::Zero(a) => RelationConnections::Zero(a),
418 RelationConnections::One([a]) => {
419 if a.1 == entity {
420 RelationConnections::Zero([])
421 } else {
422 RelationConnections::One([a])
423 }
424 }
425 RelationConnections::More(mut vec) => {
426 if let Some(index) = vec.iter().position(|a| a.1 == entity) {
427 vec.swap_remove(index);
428 }
429 if vec.len() == 1 {
430 RelationConnections::One([vec.remove(0)])
431 } else if vec.is_empty() {
432 RelationConnections::Zero([])
433 } else {
434 RelationConnections::More(vec)
435 }
436 }
437 }
438 }
439
440 pub fn has(&self, entity: Entity) -> bool {
441 match &self.connections {
442 RelationConnections::Zero(_) => false,
443 RelationConnections::One([a]) => a.1 == entity,
444 RelationConnections::More(vec) => vec.iter().any(|(_, e)| *e == entity),
445 }
446 }
447
448 pub fn payload(&self, entity: Entity) -> Option<&T> {
449 match &self.connections {
450 RelationConnections::Zero(_) => None,
451 RelationConnections::One([a]) => {
452 if a.1 == entity {
453 Some(&a.0)
454 } else {
455 None
456 }
457 }
458 RelationConnections::More(vec) => {
459 vec.iter()
460 .find_map(|(p, e)| if *e == entity { Some(p) } else { None })
461 }
462 }
463 }
464
465 pub fn payload_mut(&mut self, entity: Entity) -> Option<&mut T> {
466 match &mut self.connections {
467 RelationConnections::Zero(_) => None,
468 RelationConnections::One([a]) => {
469 if a.1 == entity {
470 Some(&mut a.0)
471 } else {
472 None
473 }
474 }
475 RelationConnections::More(vec) => {
476 vec.iter_mut()
477 .find_map(|(p, e)| if *e == entity { Some(p) } else { None })
478 }
479 }
480 }
481
482 pub fn entities(&self) -> impl Iterator<Item = Entity> + '_ {
483 match &self.connections {
484 RelationConnections::Zero(a) => a.iter(),
485 RelationConnections::One(a) => a.iter(),
486 RelationConnections::More(vec) => vec.iter(),
487 }
488 .map(|(_, e)| *e)
489 }
490
491 pub fn iter(&self) -> impl Iterator<Item = (&T, Entity)> {
492 match &self.connections {
493 RelationConnections::Zero(a) => a.iter(),
494 RelationConnections::One(a) => a.iter(),
495 RelationConnections::More(vec) => vec.iter(),
496 }
497 .map(|(p, e)| (p, *e))
498 }
499
500 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&mut T, Entity)> {
501 match &mut self.connections {
502 RelationConnections::Zero(a) => a.iter_mut(),
503 RelationConnections::One(a) => a.iter_mut(),
504 RelationConnections::More(vec) => vec.iter_mut(),
505 }
506 .map(|(p, e)| (p, *e))
507 }
508}
509
510pub struct RelationsTraverseIter<'a, const LOCKING: bool, T: Component> {
511 world: &'a World,
512 incoming: bool,
513 stack: VecDeque<Entity>,
514 visited: HashSet<Entity>,
515 _phantom: PhantomData<fn() -> T>,
516}
517
518impl<const LOCKING: bool, T: Component> Iterator for RelationsTraverseIter<'_, LOCKING, T> {
519 type Item = Entity;
520
521 fn next(&mut self) -> Option<Self::Item> {
522 while let Some(entity) = self.stack.pop_front() {
523 if self.visited.contains(&entity) {
524 continue;
525 }
526 self.visited.insert(entity);
527 if self.incoming {
528 for (entity, _, _) in self.world.relations_incomming::<LOCKING, T>(entity) {
529 if self.stack.len() == self.stack.capacity() {
530 self.stack.reserve_exact(self.stack.capacity());
531 }
532 self.stack.push_back(entity);
533 }
534 } else {
535 for (_, _, entity) in self.world.relations_outgoing::<LOCKING, T>(entity) {
536 if self.stack.len() == self.stack.capacity() {
537 self.stack.reserve_exact(self.stack.capacity());
538 }
539 self.stack.push_back(entity);
540 }
541 }
542 return Some(entity);
543 }
544 None
545 }
546}
547
548#[derive(Default, Clone)]
549pub struct WorldChanges {
550 table: HashMap<Entity, Vec<TypeHash>>,
551}
552
553impl WorldChanges {
554 pub fn clear(&mut self) {
555 self.table.clear();
556 }
557
558 pub fn has_entity(&self, entity: Entity) -> bool {
559 self.table.contains_key(&entity)
560 }
561
562 pub fn has_entity_component<T>(&self, entity: Entity) -> bool {
563 self.has_entity_component_raw(entity, TypeHash::of::<T>())
564 }
565
566 pub fn has_entity_component_raw(&self, entity: Entity, type_hash: TypeHash) -> bool {
567 self.table
568 .get(&entity)
569 .map(|components| components.contains(&type_hash))
570 .unwrap_or_default()
571 }
572
573 pub fn has_component<T>(&self) -> bool {
574 self.has_component_raw(TypeHash::of::<T>())
575 }
576
577 pub fn has_component_raw(&self, type_hash: TypeHash) -> bool {
578 self.table
579 .values()
580 .any(|components| components.contains(&type_hash))
581 }
582
583 pub fn iter(&self) -> impl Iterator<Item = (Entity, &[TypeHash])> {
584 self.table
585 .iter()
586 .map(|(entity, components)| (*entity, components.as_slice()))
587 }
588
589 pub fn iter_of<T>(&self) -> impl Iterator<Item = Entity> + '_ {
590 self.iter_of_raw(TypeHash::of::<T>())
591 }
592
593 pub fn iter_of_raw(&self, type_hash: TypeHash) -> impl Iterator<Item = Entity> + '_ {
594 self.table
595 .iter()
596 .filter(move |(_, components)| components.contains(&type_hash))
597 .map(|(entity, _)| *entity)
598 }
599}
600
601pub struct World {
602 pub new_archetype_capacity: usize,
603 entities: EntityMap,
604 archetypes: ArchetypeMap,
605 added: WorldChanges,
606 removed: WorldChanges,
607 updated: Arc<RwLock<WorldChanges>>,
608}
609
610impl Default for World {
611 fn default() -> Self {
612 World {
613 new_archetype_capacity: 128,
614 entities: Default::default(),
615 archetypes: Default::default(),
616 added: Default::default(),
617 removed: Default::default(),
618 updated: Default::default(),
619 }
620 }
621}
622
623impl World {
624 #[inline]
625 pub fn with_new_archetype_capacity(mut self, value: usize) -> Self {
626 self.new_archetype_capacity = value;
627 self
628 }
629
630 #[inline]
631 pub fn is_empty(&self) -> bool {
632 self.entities.is_empty()
633 }
634
635 #[inline]
636 pub fn len(&self) -> usize {
637 self.entities.len()
638 }
639
640 #[inline]
641 pub fn entities(&self) -> impl Iterator<Item = Entity> + '_ {
642 self.entities.iter()
643 }
644
645 #[inline]
646 pub(crate) fn entity_archetype_id(&self, entity: Entity) -> Result<u32, WorldError> {
647 self.entities.get(entity)
648 }
649
650 #[inline]
651 pub fn archetypes(&self) -> impl Iterator<Item = &Archetype> {
652 self.archetypes.iter()
653 }
654
655 #[inline]
656 pub fn archetypes_mut(&mut self) -> impl Iterator<Item = &mut Archetype> {
657 self.archetypes.iter_mut()
658 }
659
660 #[inline]
661 pub(crate) fn archetype_by_id(&self, id: u32) -> Result<&Archetype, WorldError> {
662 self.archetypes.get(id)
663 }
664
665 pub fn added(&self) -> &WorldChanges {
666 &self.added
667 }
668
669 pub fn removed(&self) -> &WorldChanges {
670 &self.removed
671 }
672
673 pub fn updated(&self) -> Option<RwLockReadGuard<WorldChanges>> {
674 self.updated.try_read().ok()
675 }
676
677 pub fn entity_did_changed(&self, entity: Entity) -> bool {
678 self.added.has_entity(entity)
679 || self.removed.has_entity(entity)
680 || self
681 .updated
682 .try_read()
683 .ok()
684 .map(|updated| updated.has_entity(entity))
685 .unwrap_or_default()
686 }
687
688 pub fn component_did_changed<T>(&self) -> bool {
689 self.component_did_changed_raw(TypeHash::of::<T>())
690 }
691
692 pub fn component_did_changed_raw(&self, type_hash: TypeHash) -> bool {
693 self.added.has_component_raw(type_hash)
694 || self.removed.has_component_raw(type_hash)
695 || self
696 .updated
697 .try_read()
698 .ok()
699 .map(|updated| updated.has_component_raw(type_hash))
700 .unwrap_or_default()
701 }
702
703 pub fn entity_component_did_changed<T>(&self, entity: Entity) -> bool {
704 self.entity_component_did_changed_raw(entity, TypeHash::of::<T>())
705 }
706
707 pub fn entity_component_did_changed_raw(&self, entity: Entity, type_hash: TypeHash) -> bool {
708 self.added.has_entity_component_raw(entity, type_hash)
709 || self.removed.has_entity_component_raw(entity, type_hash)
710 || self
711 .updated
712 .try_read()
713 .ok()
714 .map(|updated| updated.has_entity_component_raw(entity, type_hash))
715 .unwrap_or_default()
716 }
717
718 pub fn update<T>(&self, entity: Entity) {
719 self.update_raw(entity, TypeHash::of::<T>());
720 }
721
722 pub fn update_raw(&self, entity: Entity, type_hash: TypeHash) {
723 if let Ok(mut updated) = self.updated.try_write() {
724 let components = updated.table.entry(entity).or_default();
725 if !components.contains(&type_hash) {
726 components.push(type_hash);
727 }
728 }
729 }
730
731 pub fn clear_changes(&mut self) {
732 self.added.clear();
733 self.removed.clear();
734 if let Ok(mut updated) = self.updated.try_write() {
735 updated.clear();
736 }
737 }
738
739 #[inline]
740 pub fn clear(&mut self) {
741 self.clear_changes();
742 self.archetypes.clear();
743 self.entities.clear();
744 }
745
746 pub fn spawn(&mut self, bundle: impl Bundle) -> Result<Entity, WorldError> {
747 let bundle_columns = bundle.columns();
748 if bundle_columns.is_empty() {
749 return Err(WorldError::EmptyColumnSet);
750 }
751 let bundle_types = bundle_columns
752 .iter()
753 .map(|column| column.type_hash())
754 .collect::<Vec<_>>();
755 let (entity, id) = self.entities.acquire()?;
756 let id = if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&bundle_columns)
757 {
758 *id = Some(archetype_id);
759 archetype_id
760 } else {
761 let (archetype_id, archetype_slot) = match self.archetypes.acquire() {
762 Ok(result) => result,
763 Err(error) => {
764 self.entities.release(entity)?;
765 return Err(error);
766 }
767 };
768 let archetype = match Archetype::new(bundle_columns, self.new_archetype_capacity) {
769 Ok(result) => result,
770 Err(error) => {
771 self.entities.release(entity)?;
772 return Err(error.into());
773 }
774 };
775 *archetype_slot = Some(archetype);
776 *id = Some(archetype_id);
777 archetype_id
778 };
779 let archetype = match self.archetypes.get_mut(id) {
780 Ok(result) => result,
781 Err(error) => {
782 self.entities.release(entity)?;
783 return Err(error);
784 }
785 };
786 match archetype.insert(entity, bundle) {
787 Ok(_) => {
788 self.added
789 .table
790 .entry(entity)
791 .or_default()
792 .extend(bundle_types);
793 Ok(entity)
794 }
795 Err(error) => {
796 self.entities.release(entity)?;
797 Err(error.into())
798 }
799 }
800 }
801
802 pub unsafe fn spawn_uninitialized<T: BundleColumns>(
804 &mut self,
805 ) -> Result<(Entity, ArchetypeEntityRowAccess), WorldError> {
806 self.spawn_uninitialized_raw(T::columns_static())
807 }
808
809 pub unsafe fn spawn_uninitialized_raw(
811 &mut self,
812 columns: Vec<ArchetypeColumnInfo>,
813 ) -> Result<(Entity, ArchetypeEntityRowAccess), WorldError> {
814 if columns.is_empty() {
815 return Err(WorldError::EmptyColumnSet);
816 }
817 let bundle_types = columns
818 .iter()
819 .map(|column| column.type_hash())
820 .collect::<Vec<_>>();
821 let (entity, id) = self.entities.acquire()?;
822 let id = if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&columns) {
823 *id = Some(archetype_id);
824 archetype_id
825 } else {
826 let (archetype_id, archetype_slot) = match self.archetypes.acquire() {
827 Ok(result) => result,
828 Err(error) => {
829 self.entities.release(entity)?;
830 return Err(error);
831 }
832 };
833 let archetype = match Archetype::new(columns, self.new_archetype_capacity) {
834 Ok(result) => result,
835 Err(error) => {
836 self.entities.release(entity)?;
837 return Err(error.into());
838 }
839 };
840 *archetype_slot = Some(archetype);
841 *id = Some(archetype_id);
842 archetype_id
843 };
844 let archetype = match self.archetypes.get_mut(id) {
845 Ok(result) => result,
846 Err(error) => {
847 self.entities.release(entity)?;
848 return Err(error);
849 }
850 };
851 match archetype.add(entity) {
852 Ok(result) => {
853 self.added
854 .table
855 .entry(entity)
856 .or_default()
857 .extend(bundle_types);
858 Ok((entity, result))
859 }
860 Err(error) => {
861 self.entities.release(entity)?;
862 Err(error.into())
863 }
864 }
865 }
866
867 pub fn despawn(&mut self, entity: Entity) -> Result<(), WorldError> {
868 let id = self.entities.release(entity)?;
869 let archetype = self.archetypes.get_mut(id).unwrap();
870 match archetype.remove(entity) {
871 Ok(_) => {
872 self.removed
873 .table
874 .entry(entity)
875 .or_default()
876 .extend(archetype.columns().map(|column| column.type_hash()));
877 Ok(())
878 }
879 Err(error) => {
880 self.entities.acquire()?;
881 Err(error.into())
882 }
883 }
884 }
885
886 pub unsafe fn despawn_uninitialized(&mut self, entity: Entity) -> Result<(), WorldError> {
888 let id = self.entities.release(entity)?;
889 let archetype = self.archetypes.get_mut(id).unwrap();
890 match archetype.remove_uninitialized(entity) {
891 Ok(_) => {
892 self.removed
893 .table
894 .entry(entity)
895 .or_default()
896 .extend(archetype.columns().map(|column| column.type_hash()));
897 Ok(())
898 }
899 Err(error) => {
900 self.entities.acquire()?;
901 Err(error.into())
902 }
903 }
904 }
905
906 pub fn insert(&mut self, entity: Entity, bundle: impl Bundle) -> Result<(), WorldError> {
907 let bundle_columns = bundle.columns();
908 if bundle_columns.is_empty() {
909 return Err(WorldError::EmptyColumnSet);
910 }
911 let bundle_types = bundle_columns
912 .iter()
913 .map(|column| column.type_hash())
914 .collect::<Vec<_>>();
915 let old_id = self.entities.get(entity)?;
916 let mut new_columns = self
917 .archetypes
918 .get_mut(old_id)?
919 .columns()
920 .cloned()
921 .collect::<Vec<_>>();
922 for column in bundle_columns {
923 if !new_columns
924 .iter()
925 .any(|c| c.type_hash() == column.type_hash())
926 {
927 new_columns.push(column);
928 }
929 }
930 if let Some(new_id) = self.archetypes.find_by_columns_exact(&new_columns) {
931 if new_id == old_id {
932 return Ok(());
933 }
934 let [old_archetype, new_archetype] = self.archetypes.get_mut_two([old_id, new_id])?;
935 let access = old_archetype.transfer(new_archetype, entity)?;
936 bundle.initialize_into(&access);
937 self.entities.set(entity, new_id)?;
938 } else {
939 let mut archetype = Archetype::new(new_columns, self.new_archetype_capacity)?;
940 let access = self
941 .archetypes
942 .get_mut(old_id)
943 .unwrap()
944 .transfer(&mut archetype, entity)?;
945 bundle.initialize_into(&access);
946 drop(access);
947 let (new_id, archetype_slot) = self.archetypes.acquire()?;
948 *archetype_slot = Some(archetype);
949 self.entities.set(entity, new_id)?;
950 }
951 self.added
952 .table
953 .entry(entity)
954 .or_default()
955 .extend(bundle_types);
956 Ok(())
957 }
958
959 pub fn remove<T: BundleColumns>(&mut self, entity: Entity) -> Result<(), WorldError> {
960 self.remove_raw(entity, T::columns_static())
961 }
962
963 pub fn remove_raw(
964 &mut self,
965 entity: Entity,
966 columns: Vec<ArchetypeColumnInfo>,
967 ) -> Result<(), WorldError> {
968 if columns.is_empty() {
969 return Err(WorldError::EmptyColumnSet);
970 }
971 let bundle_types = columns
972 .iter()
973 .map(|column| column.type_hash())
974 .collect::<Vec<_>>();
975 let old_id = self.entities.get(entity)?;
976 let mut new_columns = self
977 .archetypes
978 .get_mut(old_id)?
979 .columns()
980 .cloned()
981 .collect::<Vec<_>>();
982 let despawn = new_columns.is_empty();
983 for column in columns {
984 if let Some(index) = new_columns
985 .iter()
986 .position(|c| c.type_hash() == column.type_hash())
987 {
988 new_columns.swap_remove(index);
989 }
990 }
991 if let Some(new_id) = self.archetypes.find_by_columns_exact(&new_columns) {
992 if new_id == old_id {
993 return Ok(());
994 }
995 let [old_archetype, new_archetype] = self.archetypes.get_mut_two([old_id, new_id])?;
996 old_archetype.transfer(new_archetype, entity)?;
997 self.entities.set(entity, new_id)?;
998 } else {
999 let mut archetype = Archetype::new(new_columns, self.new_archetype_capacity)?;
1000 self.archetypes
1001 .get_mut(old_id)
1002 .unwrap()
1003 .transfer(&mut archetype, entity)?;
1004 let (new_id, archetype_slot) = self.archetypes.acquire()?;
1005 *archetype_slot = Some(archetype);
1006 self.entities.set(entity, new_id)?;
1007 }
1008 if despawn {
1009 let _ = self.entities.release(entity);
1010 }
1011 self.removed
1012 .table
1013 .entry(entity)
1014 .or_default()
1015 .extend(bundle_types);
1016 Ok(())
1017 }
1018
1019 pub fn merge<const LOCKING: bool>(
1020 &mut self,
1021 mut other: Self,
1022 processor: &WorldProcessor,
1023 ) -> Result<(), WorldError> {
1024 let mut mappings = HashMap::<_, _>::with_capacity(other.len());
1025 let mut archetype_offsets = Vec::with_capacity(other.archetypes().count());
1026 for archetype_from in other.archetypes_mut() {
1027 let columns = archetype_from.columns().cloned().collect::<Vec<_>>();
1028 let archetype_id =
1029 if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&columns) {
1030 archetype_id
1031 } else {
1032 let (archetype_id, archetype_slot) = self.archetypes.acquire()?;
1033 let archetype = Archetype::new(columns.clone(), self.new_archetype_capacity)?;
1034 *archetype_slot = Some(archetype);
1035 archetype_id
1036 };
1037 let archetype = self.archetypes.get_mut(archetype_id)?;
1038 let offset = archetype.len();
1039 let entities_from = archetype_from.entities().iter().collect::<Vec<_>>();
1040 for entity_from in entities_from {
1041 let (entity, access) = unsafe { self.spawn_uninitialized_raw(columns.clone())? };
1042 let access_from = match archetype_from.row::<LOCKING>(entity_from) {
1043 Ok(access_from) => access_from,
1044 Err(error) => {
1045 drop(access);
1046 unsafe { self.despawn_uninitialized(entity)? };
1047 return Err(error.into());
1048 }
1049 };
1050 for column in &columns {
1051 unsafe {
1052 let data = access.data(column.type_hash()).unwrap();
1053 let data_from = access_from.data(column.type_hash()).unwrap();
1054 data.copy_from(data_from, column.layout().size());
1055 }
1056 }
1057 mappings.insert(entity_from, entity);
1058 }
1059 archetype_offsets.push((columns, offset));
1060 unsafe { archetype_from.clear_uninitialized() };
1061 }
1062 for (columns, offset) in archetype_offsets {
1063 if let Some(id) = self.archetypes.find_by_columns_exact(&columns) {
1064 let archetype = self.archetype_by_id(id)?;
1065 for column in archetype.columns() {
1066 let access = archetype.dynamic_column::<LOCKING>(column.type_hash(), true)?;
1067 for index in offset..archetype.len() {
1068 unsafe {
1069 processor.remap_entities_raw(
1070 column.type_hash(),
1071 access.data(index)?,
1072 WorldProcessorEntityMapping::new(&mappings),
1073 );
1074 }
1075 }
1076 }
1077 }
1078 }
1079 Ok(())
1080 }
1081
1082 pub fn has_entity(&self, entity: Entity) -> bool {
1083 self.entities.get(entity).is_ok()
1084 }
1085
1086 pub fn has_entity_component<T: Component>(&self, entity: Entity) -> bool {
1087 self.has_entity_component_raw(entity, TypeHash::of::<T>())
1088 }
1089
1090 pub fn has_entity_component_raw(&self, entity: Entity, component: TypeHash) -> bool {
1091 self.entities
1092 .get(entity)
1093 .and_then(|index| self.archetypes.get(index))
1094 .map(|archetype| archetype.has_type(component))
1095 .unwrap_or_default()
1096 }
1097
1098 pub fn find_by<const LOCKING: bool, T: Component + PartialEq>(
1099 &self,
1100 data: &T,
1101 ) -> Option<Entity> {
1102 for (entity, component) in self.query::<LOCKING, (Entity, &T)>() {
1103 if component == data {
1104 return Some(entity);
1105 }
1106 }
1107 None
1108 }
1109
1110 pub fn component<const LOCKING: bool, T: Component>(
1111 &self,
1112 entity: Entity,
1113 ) -> Result<ComponentRef<LOCKING, T>, WorldError> {
1114 Ok(ComponentRef {
1115 inner: self.get::<LOCKING, T>(entity, false)?,
1116 })
1117 }
1118
1119 pub fn component_mut<const LOCKING: bool, T: Component>(
1120 &self,
1121 entity: Entity,
1122 ) -> Result<ComponentRefMut<LOCKING, T>, WorldError> {
1123 Ok(ComponentRefMut {
1124 inner: self.get::<LOCKING, T>(entity, true)?,
1125 })
1126 }
1127
1128 pub fn get<const LOCKING: bool, T: Component>(
1129 &self,
1130 entity: Entity,
1131 unique: bool,
1132 ) -> Result<ArchetypeEntityColumnAccess<LOCKING, T>, WorldError> {
1133 Ok(self
1134 .archetypes
1135 .get(self.entities.get(entity)?)?
1136 .entity::<LOCKING, T>(entity, unique)?)
1137 }
1138
1139 pub fn dynamic_get<const LOCKING: bool>(
1140 &self,
1141 type_hash: TypeHash,
1142 entity: Entity,
1143 unique: bool,
1144 ) -> Result<ArchetypeDynamicEntityColumnAccess<LOCKING>, WorldError> {
1145 Ok(self
1146 .archetypes
1147 .get(self.entities.get(entity)?)?
1148 .dynamic_entity::<LOCKING>(type_hash, entity, unique)?)
1149 }
1150
1151 pub fn row<const LOCKING: bool>(
1152 &self,
1153 entity: Entity,
1154 ) -> Result<ArchetypeEntityRowAccess, WorldError> {
1155 Ok(self
1156 .archetypes
1157 .get(self.entities.get(entity)?)?
1158 .row::<LOCKING>(entity)?)
1159 }
1160
1161 pub fn query<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>>(
1162 &'a self,
1163 ) -> TypedQueryIter<'a, LOCKING, Fetch> {
1164 TypedQueryIter::new(self)
1165 }
1166
1167 pub fn dynamic_query<'a, const LOCKING: bool>(
1168 &'a self,
1169 filter: &DynamicQueryFilter,
1170 ) -> DynamicQueryIter<'a, LOCKING> {
1171 DynamicQueryIter::new(filter, self)
1172 }
1173
1174 pub fn lookup<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1175 &'a self,
1176 entities: impl IntoIterator<Item = Entity> + 'a,
1177 ) -> TypedLookupIter<'a, LOCKING, Fetch> {
1178 TypedLookupIter::new(self, entities)
1179 }
1180
1181 pub fn lookup_access<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1182 &'a self,
1183 ) -> TypedLookupAccess<'a, LOCKING, Fetch> {
1184 TypedLookupAccess::new(self)
1185 }
1186
1187 pub fn dynamic_lookup<'a, const LOCKING: bool>(
1188 &'a self,
1189 filter: &DynamicQueryFilter,
1190 entities: impl IntoIterator<Item = Entity> + 'a,
1191 ) -> DynamicLookupIter<'a, LOCKING> {
1192 DynamicLookupIter::new(filter, self, entities)
1193 }
1194
1195 pub fn dynamic_lookup_access<'a, const LOCKING: bool>(
1196 &'a self,
1197 filter: &DynamicQueryFilter,
1198 ) -> DynamicLookupAccess<'a, LOCKING> {
1199 DynamicLookupAccess::new(filter, self)
1200 }
1201
1202 pub fn relate<const LOCKING: bool, T: Component>(
1203 &mut self,
1204 payload: T,
1205 from: Entity,
1206 to: Entity,
1207 ) -> Result<(), WorldError> {
1208 if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1209 if let Some(relation) = relation.write() {
1210 relation.add(payload, to);
1211 }
1212 return Ok(());
1213 }
1214 self.insert(from, (Relation::<T>::default().with(payload, to),))
1215 }
1216
1217 pub fn unrelate<const LOCKING: bool, T: Component>(
1218 &mut self,
1219 from: Entity,
1220 to: Entity,
1221 ) -> Result<(), WorldError> {
1222 let remove = if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1223 if let Some(relation) = relation.write() {
1224 relation.remove(to);
1225 relation.is_empty()
1226 } else {
1227 false
1228 }
1229 } else {
1230 false
1231 };
1232 if remove {
1233 self.remove::<(Relation<T>,)>(from)?;
1234 }
1235 Ok(())
1236 }
1237
1238 pub fn unrelate_any<const LOCKING: bool, T: Component>(
1239 &mut self,
1240 entity: Entity,
1241 ) -> Result<(), WorldError> {
1242 let to_remove = self
1243 .query::<LOCKING, (Entity, &mut Relation<T>)>()
1244 .filter_map(|(e, relation)| {
1245 relation.remove(entity);
1246 if relation.is_empty() {
1247 Some(e)
1248 } else {
1249 None
1250 }
1251 })
1252 .collect::<Vec<_>>();
1253 for entity in to_remove {
1254 self.remove::<(Relation<T>,)>(entity)?;
1255 }
1256 Ok(())
1257 }
1258
1259 pub fn has_relation<const LOCKING: bool, T: Component>(
1260 &self,
1261 from: Entity,
1262 to: Entity,
1263 ) -> bool {
1264 self.get::<LOCKING, Relation<T>>(from, false)
1265 .ok()
1266 .and_then(|relation| Some(relation.read()?.has(to)))
1267 .unwrap_or_default()
1268 }
1269
1270 pub fn relations<const LOCKING: bool, T: Component>(
1271 &self,
1272 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1273 self.query::<LOCKING, (Entity, &Relation<T>)>()
1274 .flat_map(|(from, relation)| {
1275 relation
1276 .iter()
1277 .map(move |(payload, to)| (from, payload, to))
1278 })
1279 }
1280
1281 pub fn relations_mut<const LOCKING: bool, T: Component>(
1282 &self,
1283 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1284 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1285 .flat_map(|(from, relation)| {
1286 relation
1287 .iter_mut()
1288 .map(move |(payload, to)| (from, payload, to))
1289 })
1290 }
1291
1292 pub fn relations_outgoing<const LOCKING: bool, T: Component>(
1293 &self,
1294 from: Entity,
1295 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1296 self.query::<LOCKING, (Entity, &Relation<T>)>()
1297 .filter(move |(entity, _)| *entity == from)
1298 .flat_map(|(from, relation)| {
1299 relation
1300 .iter()
1301 .map(move |(payload, to)| (from, payload, to))
1302 })
1303 }
1304
1305 pub fn relations_outgoing_mut<const LOCKING: bool, T: Component>(
1306 &self,
1307 from: Entity,
1308 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1309 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1310 .filter(move |(entity, _)| *entity == from)
1311 .flat_map(|(from, relation)| {
1312 relation
1313 .iter_mut()
1314 .map(move |(payload, to)| (from, payload, to))
1315 })
1316 }
1317
1318 pub fn relations_incomming<const LOCKING: bool, T: Component>(
1319 &self,
1320 to: Entity,
1321 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1322 self.query::<LOCKING, (Entity, &Relation<T>)>()
1323 .flat_map(move |(from, relation)| {
1324 relation
1325 .iter()
1326 .filter(move |(_, entity)| *entity == to)
1327 .map(move |(payload, to)| (from, payload, to))
1328 })
1329 }
1330
1331 pub fn relations_incomming_mut<const LOCKING: bool, T: Component>(
1332 &self,
1333 to: Entity,
1334 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1335 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1336 .flat_map(move |(from, relation)| {
1337 relation
1338 .iter_mut()
1339 .filter(move |(_, entity)| *entity == to)
1340 .map(move |(payload, to)| (from, payload, to))
1341 })
1342 }
1343
1344 pub fn traverse_outgoing<const LOCKING: bool, T: Component>(
1345 &self,
1346 entities: impl IntoIterator<Item = Entity>,
1347 ) -> RelationsTraverseIter<LOCKING, T> {
1348 RelationsTraverseIter {
1349 world: self,
1350 incoming: false,
1351 stack: entities.into_iter().collect(),
1352 visited: Default::default(),
1353 _phantom: Default::default(),
1354 }
1355 }
1356
1357 pub fn traverse_incoming<const LOCKING: bool, T: Component>(
1358 &self,
1359 entities: impl IntoIterator<Item = Entity>,
1360 ) -> RelationsTraverseIter<LOCKING, T> {
1361 RelationsTraverseIter {
1362 world: self,
1363 incoming: true,
1364 stack: entities.into_iter().collect(),
1365 visited: Default::default(),
1366 _phantom: Default::default(),
1367 }
1368 }
1369}
1370
1371#[cfg(test)]
1372mod tests {
1373 use super::*;
1374 use crate::{
1375 commands::{CommandBuffer, DespawnCommand},
1376 query::{Exclude, Include, Update},
1377 };
1378 use std::{
1379 sync::{Arc, RwLock},
1380 thread::spawn,
1381 time::{Duration, Instant},
1382 };
1383
1384 #[test]
1385 fn test_world_changes() {
1386 let mut world = World::default();
1387 assert!(world.is_empty());
1388 assert!(world.spawn(()).is_err());
1389
1390 let (entity, row) = unsafe { world.spawn_uninitialized::<(u8, u16, u32)>().unwrap() };
1391 assert_eq!(entity, Entity::new(0, 0).unwrap());
1392 unsafe { row.initialize(1u8).unwrap() };
1393 unsafe { row.initialize(2u16).unwrap() };
1394 unsafe { row.initialize(3u32).unwrap() };
1395 assert_eq!(*row.read::<u8>().unwrap(), 1);
1396 assert_eq!(*row.read::<u16>().unwrap(), 2);
1397 assert_eq!(*row.read::<u32>().unwrap(), 3);
1398 drop(row);
1399 world.despawn(entity).unwrap();
1400 assert!(world.is_empty());
1401
1402 let entity = world.spawn((1u8, 2u16, 3u32)).unwrap();
1403 assert_eq!(entity, Entity::new(0, 1).unwrap());
1404 assert_eq!(
1405 *world
1406 .get::<true, u8>(entity, false)
1407 .unwrap()
1408 .read()
1409 .unwrap(),
1410 1
1411 );
1412 assert_eq!(
1413 *world
1414 .get::<true, u16>(entity, false)
1415 .unwrap()
1416 .read()
1417 .unwrap(),
1418 2
1419 );
1420 assert_eq!(
1421 *world
1422 .get::<true, u32>(entity, false)
1423 .unwrap()
1424 .read()
1425 .unwrap(),
1426 3
1427 );
1428 assert!(world.get::<true, u64>(entity, false).is_err());
1429 assert_eq!(world.len(), 1);
1430
1431 world.insert(entity, (4u64,)).unwrap();
1432 assert_eq!(
1433 *world
1434 .get::<true, u8>(entity, false)
1435 .unwrap()
1436 .read()
1437 .unwrap(),
1438 1
1439 );
1440 assert_eq!(
1441 *world
1442 .get::<true, u16>(entity, false)
1443 .unwrap()
1444 .read()
1445 .unwrap(),
1446 2
1447 );
1448 assert_eq!(
1449 *world
1450 .get::<true, u32>(entity, false)
1451 .unwrap()
1452 .read()
1453 .unwrap(),
1454 3
1455 );
1456 assert_eq!(
1457 *world
1458 .get::<true, u64>(entity, false)
1459 .unwrap()
1460 .read()
1461 .unwrap(),
1462 4
1463 );
1464
1465 world.remove::<(u8,)>(entity).unwrap();
1466 assert!(world.get::<true, u8>(entity, false).is_err());
1467 assert_eq!(
1468 *world
1469 .get::<true, u16>(entity, false)
1470 .unwrap()
1471 .read()
1472 .unwrap(),
1473 2
1474 );
1475 assert_eq!(
1476 *world
1477 .get::<true, u32>(entity, false)
1478 .unwrap()
1479 .read()
1480 .unwrap(),
1481 3
1482 );
1483 assert_eq!(
1484 *world
1485 .get::<true, u64>(entity, false)
1486 .unwrap()
1487 .read()
1488 .unwrap(),
1489 4
1490 );
1491
1492 world.clear();
1493 assert!(world.is_empty());
1494 }
1495
1496 #[test]
1497 fn test_world_query() {
1498 const N: usize = if cfg!(miri) { 10 } else { 1000 };
1499
1500 let mut world = World::default().with_new_archetype_capacity(N);
1501
1502 for index in 0..N {
1503 world.spawn((index as u8,)).unwrap();
1504 }
1505 for index in N..(N * 2) {
1506 world.spawn((index as u8, index as u16)).unwrap();
1507 }
1508 for index in (N * 2)..(N * 3) {
1509 world.spawn((index as u16,)).unwrap();
1510 }
1511
1512 for (index, v) in world.query::<true, &u8>().enumerate() {
1513 assert_eq!(*v, index as u8);
1514 }
1515
1516 for (index, item) in world
1517 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>())
1518 .enumerate()
1519 {
1520 let v = item.read::<u8>().unwrap().read::<u8>().unwrap();
1521 assert_eq!(*v, index as u8);
1522 }
1523
1524 for (index, v) in world.query::<true, &u16>().enumerate() {
1525 assert_eq!(*v, (index + N) as u16);
1526 }
1527
1528 for (index, item) in world
1529 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u16>())
1530 .enumerate()
1531 {
1532 let v = item.read::<u16>().unwrap().read::<u16>().unwrap();
1533 assert_eq!(*v, (index + N) as u16);
1534 }
1535
1536 for (index, (entity, a, b)) in world.query::<true, (Entity, &u8, &u16)>().enumerate() {
1537 assert!(entity.is_valid());
1538 assert_eq!(*a, (index + N) as u8);
1539 assert_eq!(*b, (index + N) as u16);
1540 }
1541
1542 for (index, item) in world
1543 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().read::<u16>())
1544 .enumerate()
1545 {
1546 let a = item.read::<u8>().unwrap().read::<u8>().unwrap();
1547 let b = item.read::<u16>().unwrap().read::<u16>().unwrap();
1548 assert!(item.entity().is_valid());
1549 assert_eq!(*a, (index + N) as u8);
1550 assert_eq!(*b, (index + N) as u16);
1551 }
1552
1553 for (index, (a, b)) in world.query::<true, (&u8, Option<&u16>)>().enumerate() {
1554 assert_eq!(*a, index as u8);
1555 if let Some(b) = b {
1556 assert_eq!(*b, index as u16);
1557 }
1558 }
1559
1560 for (entity, _, _) in world.query::<true, (Entity, &u8, Include<u16>)>() {
1561 assert!((entity.id() as usize) >= N);
1562 assert!((entity.id() as usize) < N * 2);
1563 }
1564
1565 for item in world
1566 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().include::<u16>())
1567 {
1568 assert!((item.entity().id() as usize) >= N);
1569 assert!((item.entity().id() as usize) < N * 2);
1570 }
1571
1572 for (entity, _, _) in world.query::<true, (Entity, &u8, Exclude<u16>)>() {
1573 assert!((entity.id() as usize) < N);
1574 }
1575
1576 for item in world
1577 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().exclude::<u16>())
1578 {
1579 assert!((item.entity().id() as usize) < N);
1580 }
1581 }
1582
1583 #[test]
1584 fn test_world_lookup() {
1585 const N: usize = if cfg!(miri) { 10 } else { 1000 };
1586
1587 let mut world = World::default().with_new_archetype_capacity(N);
1588
1589 let mut entities = vec![];
1590 for index in 0..N {
1591 let entity = world.spawn((index as u8,)).unwrap();
1592 if index % 2 == 0 {
1593 entities.push(entity);
1594 }
1595 }
1596
1597 let compare_entities = world
1598 .lookup::<true, (Entity, &u8)>(entities.iter().copied())
1599 .map(|(entity, _)| entity)
1600 .collect::<Vec<_>>();
1601 assert_eq!(compare_entities, entities);
1602
1603 let mut lookup = world.lookup_access::<true, (Entity, &u8)>();
1604 for entity in entities.iter().copied() {
1605 assert_eq!(lookup.access(entity).unwrap().0, entity);
1606 }
1607
1608 let compare_entities = world
1609 .dynamic_lookup::<true>(
1610 &DynamicQueryFilter::default().read::<u8>(),
1611 entities.iter().copied(),
1612 )
1613 .map(|item| item.entity())
1614 .collect::<Vec<_>>();
1615 assert_eq!(compare_entities, entities);
1616
1617 let lookup =
1618 world.dynamic_lookup_access::<true>(&DynamicQueryFilter::default().read::<u8>());
1619 for entity in entities.iter().copied() {
1620 let item = lookup.access(entity).unwrap();
1621 assert_eq!(item.entity(), entity);
1622 }
1623 }
1624
1625 #[test]
1626 fn test_change_detection() {
1627 let mut world = World::default();
1628
1629 for index in 0..10usize {
1630 world.spawn((index,)).unwrap();
1631 }
1632 let mut list = world.added().iter_of::<usize>().collect::<Vec<_>>();
1633 list.sort();
1634 assert_eq!(
1635 list,
1636 (0..10)
1637 .map(|index| Entity::new(index, 0).unwrap())
1638 .collect::<Vec<_>>()
1639 );
1640
1641 for mut v in world.query::<true, Update<usize>>() {
1642 *v.write_notified(&world) *= 2;
1643 }
1644 for (entity, v) in world.query::<true, (Entity, &usize)>() {
1645 assert_eq!(entity.id() as usize * 2, *v);
1646 }
1647 let mut list = world
1648 .updated()
1649 .unwrap()
1650 .iter_of::<usize>()
1651 .collect::<Vec<_>>();
1652 list.sort();
1653 assert_eq!(
1654 list,
1655 (0..10)
1656 .map(|index| Entity::new(index, 0).unwrap())
1657 .collect::<Vec<_>>()
1658 );
1659
1660 let mut commands = CommandBuffer::default();
1661 for entity in world.entities() {
1662 commands.command(DespawnCommand::new(entity));
1663 }
1664 commands.execute(&mut world);
1665 let mut list = world.removed().iter_of::<usize>().collect::<Vec<_>>();
1666 list.sort();
1667 assert_eq!(
1668 list,
1669 (0..10)
1670 .map(|index| Entity::new(index, 0).unwrap())
1671 .collect::<Vec<_>>()
1672 );
1673 }
1674
1675 #[test]
1676 fn test_zst_components() {
1677 #[derive(Debug, PartialEq, Eq)]
1678 struct Foo;
1679
1680 #[derive(Debug, PartialEq, Eq)]
1681 struct Bar(bool);
1682
1683 let mut world = World::default();
1684 world.spawn((Foo,)).unwrap();
1685 assert_eq!(world.query::<true, &Foo>().count(), 1);
1686 for v in world.query::<true, &Foo>() {
1687 assert_eq!(v, &Foo);
1688 }
1689 world.spawn((Bar(true),)).unwrap();
1690 assert_eq!(world.query::<true, &Bar>().count(), 1);
1691 for v in world.query::<true, &Bar>() {
1692 assert_eq!(v, &Bar(true));
1693 }
1694 world.spawn((Foo, Bar(false))).unwrap();
1695 assert_eq!(world.query::<true, &Foo>().count(), 2);
1696 assert_eq!(world.query::<true, &Bar>().count(), 2);
1697 assert_eq!(world.query::<true, (&Bar, &Foo)>().count(), 1);
1698 for (a, b) in world.query::<true, (&Bar, &Foo)>() {
1699 assert_eq!(a, &Bar(false));
1700 assert_eq!(b, &Foo);
1701 }
1702 }
1703
1704 #[test]
1705 fn test_world_relations() {
1706 struct Parent;
1707 struct Root;
1708
1709 let mut world = World::default();
1710 let a = world.spawn((0u8, false, Root)).unwrap();
1711 let b = world.spawn((1u8, false)).unwrap();
1712 let c = world.spawn((2u8, false)).unwrap();
1713 let d = world.spawn((3u8, false)).unwrap();
1714 world.relate::<true, _>(Parent, b, a).unwrap();
1715 world.relate::<true, _>(Parent, c, a).unwrap();
1716 world.relate::<true, _>(Parent, d, c).unwrap();
1717
1718 assert_eq!(
1719 world
1720 .relations_incomming::<true, Parent>(a)
1721 .map(|(entity, _, _)| entity)
1722 .collect::<Vec<_>>(),
1723 vec![b, c]
1724 );
1725 assert_eq!(
1726 world
1727 .relations_incomming::<true, Parent>(b)
1728 .map(|(entity, _, _)| entity)
1729 .collect::<Vec<_>>(),
1730 vec![]
1731 );
1732 assert_eq!(
1733 world
1734 .relations_incomming::<true, Parent>(c)
1735 .map(|(entity, _, _)| entity)
1736 .collect::<Vec<_>>(),
1737 vec![d]
1738 );
1739 assert_eq!(
1740 world
1741 .relations_incomming::<true, Parent>(d)
1742 .map(|(entity, _, _)| entity)
1743 .collect::<Vec<_>>(),
1744 vec![]
1745 );
1746
1747 assert_eq!(
1748 world
1749 .relations_outgoing::<true, Parent>(a)
1750 .map(|(_, _, entity)| entity)
1751 .collect::<Vec<_>>(),
1752 vec![]
1753 );
1754 assert_eq!(
1755 world
1756 .relations_outgoing::<true, Parent>(b)
1757 .map(|(_, _, entity)| entity)
1758 .collect::<Vec<_>>(),
1759 vec![a]
1760 );
1761 assert_eq!(
1762 world
1763 .relations_outgoing::<true, Parent>(c)
1764 .map(|(_, _, entity)| entity)
1765 .collect::<Vec<_>>(),
1766 vec![a]
1767 );
1768 assert_eq!(
1769 world
1770 .relations_outgoing::<true, Parent>(d)
1771 .map(|(_, _, entity)| entity)
1772 .collect::<Vec<_>>(),
1773 vec![c]
1774 );
1775
1776 assert_eq!(
1777 world
1778 .traverse_incoming::<true, Parent>([a])
1779 .collect::<Vec<_>>(),
1780 vec![a, b, c, d]
1781 );
1782
1783 for (entity, _) in world.query::<true, (Entity, Include<Root>)>() {
1784 for (other, _, _) in world.relations_incomming::<true, Parent>(entity) {
1785 let mut v = world.get::<true, bool>(other, true).unwrap();
1786 let v = v.write().unwrap();
1787 *v = !*v;
1788 }
1789 }
1790
1791 assert!(!*world.get::<true, bool>(a, false).unwrap().read().unwrap());
1792 assert!(*world.get::<true, bool>(b, false).unwrap().read().unwrap());
1793 assert!(*world.get::<true, bool>(c, false).unwrap().read().unwrap());
1794 assert!(!*world.get::<true, bool>(d, false).unwrap().read().unwrap());
1795
1796 world.unrelate::<true, Parent>(b, a).unwrap();
1797 world.unrelate::<true, Parent>(c, a).unwrap();
1798 world.unrelate::<true, Parent>(d, c).unwrap();
1799 assert!(world.query::<true, &Relation<Parent>>().count() == 0);
1800 }
1801
1802 #[test]
1803 fn test_world_async() {
1804 const N: usize = if cfg!(miri) { 10 } else { 1000 };
1805
1806 fn is_async<T: Send + Sync>() {}
1807
1808 is_async::<World>();
1809
1810 let world = Arc::new(RwLock::new(World::default().with_new_archetype_capacity(N)));
1811 let world2 = world.clone();
1812
1813 {
1814 let mut world = world.write().unwrap();
1815 for index in 0..N {
1816 world.spawn((index as u8, index as u16)).unwrap();
1817 }
1818 }
1819
1820 let handle = spawn(move || {
1821 let timer = Instant::now();
1822 while timer.elapsed() < Duration::from_secs(1) {
1823 let world = world2.read().unwrap();
1824 for v in world.query::<true, &mut u16>() {
1825 *v = v.wrapping_add(1);
1826 }
1827 }
1828 });
1829
1830 let timer = Instant::now();
1831 while timer.elapsed() < Duration::from_secs(1) {
1832 let world = world.read().unwrap();
1833 for v in world.query::<true, &mut u8>() {
1834 *v = v.wrapping_add(1);
1835 }
1836 }
1837
1838 let _ = handle.join();
1839 }
1840}