1use crate::{
2 archetype::{
3 ArchetypeColumnInfo, ArchetypeDynamicEntityColumnAccess, ArchetypeEntityColumnAccess,
4 },
5 entity::Entity,
6 query::{
7 DynamicQueryFilter, DynamicQueryItem, DynamicQueryIter, TypedQueryFetch, TypedQueryIter,
8 },
9 world::{World, WorldError},
10 Component,
11};
12use intuicio_data::type_hash::TypeHash;
13use serde::{Deserialize, Serialize};
14use std::{
15 collections::VecDeque,
16 ops::{Deref, DerefMut},
17};
18
19#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
20pub enum Multity {
21 One([Entity; 1]),
22 Two([Entity; 2]),
23 More(Vec<Entity>),
24}
25
26impl Multity {
27 pub fn new(entity: Entity) -> Self {
28 Self::One([entity])
29 }
30
31 pub fn with(mut self, entity: Entity) -> Self {
32 self.push(entity);
33 self
34 }
35
36 #[allow(clippy::len_without_is_empty)]
37 pub fn len(&self) -> usize {
38 match self {
39 Self::One(_) => 1,
40 Self::Two(_) => 2,
41 Self::More(items) => items.len(),
42 }
43 }
44
45 pub fn root(&self) -> Entity {
46 match self {
47 Self::One([entity]) => *entity,
48 Self::Two([entity, _]) => *entity,
49 Self::More(items) => *items.first().unwrap(),
50 }
51 }
52
53 pub fn entity(&self) -> Entity {
54 match self {
55 Self::One([entity]) => *entity,
56 Self::Two([_, entity]) => *entity,
57 Self::More(items) => *items.last().unwrap(),
58 }
59 }
60
61 pub fn parent(&self) -> Option<Self> {
62 let mut result = self.clone();
63 if result.pop().is_some() {
64 Some(result)
65 } else {
66 None
67 }
68 }
69
70 pub fn push(&mut self, entity: Entity) {
71 *self = match std::mem::replace(self, Self::new(Default::default())) {
72 Self::One([a]) => Self::Two([a, entity]),
73 Self::Two([a, b]) => Self::More(vec![a, b, entity]),
74 Self::More(mut items) => {
75 items.push(entity);
76 Self::More(items)
77 }
78 }
79 }
80
81 pub fn pop(&mut self) -> Option<Entity> {
82 match std::mem::replace(self, Self::new(Default::default())) {
83 Self::One([a]) => {
84 *self = Self::One([a]);
85 None
86 }
87 Self::Two([a, b]) => {
88 *self = Self::One([a]);
89 Some(b)
90 }
91 Self::More(mut items) => {
92 let result = items.pop()?;
93 match items.len() {
94 2 => {
95 *self = Self::Two([items[0], items[1]]);
96 }
97 1 => {
98 *self = Self::One([items[0]]);
99 }
100 _ => {
101 *self = Self::More(items);
102 }
103 }
104 Some(result)
105 }
106 }
107 }
108
109 pub fn prepend(&mut self, other: impl IntoIterator<Item = Entity>) {
110 *self = Self::from_iter(other.into_iter().chain(self.iter()));
111 }
112
113 pub fn append(&mut self, other: impl IntoIterator<Item = Entity>) {
114 for entity in other.into_iter() {
115 self.push(entity);
116 }
117 }
118
119 pub fn iter(&self) -> impl Iterator<Item = Entity> + '_ {
120 match self {
121 Self::One(items) => items.as_slice().iter().copied(),
122 Self::Two(items) => items.as_slice().iter().copied(),
123 Self::More(items) => items.as_slice().iter().copied(),
124 }
125 }
126
127 pub fn into_inner(self) -> Vec<Entity> {
128 self.iter().collect()
129 }
130}
131
132impl FromIterator<Entity> for Multity {
133 fn from_iter<T: IntoIterator<Item = Entity>>(iter: T) -> Self {
134 let mut iter = iter.into_iter();
135 let entity = iter.next().unwrap();
136 let mut result = Self::new(entity);
137 for entity in iter {
138 result.push(entity);
139 }
140 result
141 }
142}
143
144pub struct ArchetypeMultityColumnAccess<'a, const LOCKING: bool, T: Component> {
145 _worlds: Vec<ArchetypeEntityColumnAccess<'a, LOCKING, World>>,
146 entity: ArchetypeEntityColumnAccess<'a, LOCKING, T>,
147}
148
149impl<const LOCKING: bool, T: Component> ArchetypeMultityColumnAccess<'_, LOCKING, T> {
150 #[inline]
151 pub fn info(&self) -> &ArchetypeColumnInfo {
152 self.entity.info()
153 }
154
155 #[inline]
156 pub fn is_unique(&self) -> bool {
157 self.entity.is_unique()
158 }
159
160 #[inline]
162 pub unsafe fn data(&self) -> *mut u8 {
163 self.entity.data()
164 }
165
166 pub fn read(&self) -> Option<&T> {
167 self.entity.read()
168 }
169
170 pub fn write(&mut self) -> Option<&mut T> {
171 self.entity.write()
172 }
173}
174
175pub struct ArchetypeDynamicMultityColumnAccess<'a, const LOCKING: bool> {
176 _worlds: Vec<ArchetypeEntityColumnAccess<'a, LOCKING, World>>,
177 entity: ArchetypeDynamicEntityColumnAccess<'a, LOCKING>,
178}
179
180impl<const LOCKING: bool> ArchetypeDynamicMultityColumnAccess<'_, LOCKING> {
181 #[inline]
182 pub fn info(&self) -> &ArchetypeColumnInfo {
183 self.entity.info()
184 }
185
186 #[inline]
187 pub fn is_unique(&self) -> bool {
188 self.entity.is_unique()
189 }
190
191 #[inline]
193 pub unsafe fn data(&self) -> *mut u8 {
194 self.entity.data()
195 }
196
197 pub fn read<T: Component>(&self) -> Option<&T> {
198 self.entity.read::<T>()
199 }
200
201 pub fn write<T: Component>(&mut self) -> Option<&mut T> {
202 self.entity.write::<T>()
203 }
204}
205
206pub struct HyperComponentRef<'a, const LOCKING: bool, T: Send + Sync + 'static> {
207 inner: ArchetypeMultityColumnAccess<'a, LOCKING, T>,
208}
209
210impl<const LOCKING: bool, T: Send + Sync + 'static> Deref for HyperComponentRef<'_, LOCKING, T> {
211 type Target = T;
212
213 fn deref(&self) -> &Self::Target {
214 self.inner.read().unwrap()
215 }
216}
217
218pub struct HyperComponentRefMut<'a, const LOCKING: bool, T: Send + Sync + 'static> {
219 inner: ArchetypeMultityColumnAccess<'a, LOCKING, T>,
220}
221
222impl<const LOCKING: bool, T: Send + Sync + 'static> Deref for HyperComponentRefMut<'_, LOCKING, T> {
223 type Target = T;
224
225 fn deref(&self) -> &Self::Target {
226 self.inner.read().unwrap()
227 }
228}
229
230impl<const LOCKING: bool, T: Send + Sync + 'static> DerefMut
231 for HyperComponentRefMut<'_, LOCKING, T>
232{
233 fn deref_mut(&mut self) -> &mut Self::Target {
234 self.inner.write().unwrap()
235 }
236}
237
238pub struct MultiverseTypedQueryIter<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>> {
239 queries: VecDeque<TypedQueryIter<'a, LOCKING, Fetch>>,
240}
241
242impl<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>> Default
243 for MultiverseTypedQueryIter<'a, LOCKING, Fetch>
244{
245 fn default() -> Self {
246 Self {
247 queries: Default::default(),
248 }
249 }
250}
251
252impl<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>>
253 MultiverseTypedQueryIter<'a, LOCKING, Fetch>
254{
255 pub fn new(world: &'a World) -> Self {
256 let mut result = Self::default();
257 result.include(world);
258 result
259 }
260
261 pub fn include(&mut self, world: &'a World) {
262 self.queries.push_back(world.query::<'a, LOCKING, Fetch>());
263 for world in world.query::<'a, LOCKING, &World>() {
264 self.include(world);
265 }
266 }
267}
268
269impl<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>> Iterator
270 for MultiverseTypedQueryIter<'a, LOCKING, Fetch>
271{
272 type Item = Fetch::Value;
273
274 fn next(&mut self) -> Option<Self::Item> {
275 loop {
276 if let Some(query) = self.queries.back_mut() {
277 if let Some(result) = query.next() {
278 return Some(result);
279 }
280 self.queries.pop_back();
281 continue;
282 }
283 break;
284 }
285 None
286 }
287}
288
289pub struct MultiverseDynamicQueryIter<'a, const LOCKING: bool> {
290 queries: VecDeque<DynamicQueryIter<'a, LOCKING>>,
291}
292
293impl<const LOCKING: bool> Default for MultiverseDynamicQueryIter<'_, LOCKING> {
294 fn default() -> Self {
295 Self {
296 queries: Default::default(),
297 }
298 }
299}
300
301impl<'a, const LOCKING: bool> MultiverseDynamicQueryIter<'a, LOCKING> {
302 pub fn new(filter: &DynamicQueryFilter, world: &'a World) -> Self {
303 let mut result = Self::default();
304 result.include(filter, world);
305 result
306 }
307
308 pub fn include(&mut self, filter: &DynamicQueryFilter, world: &'a World) {
309 self.queries
310 .push_back(world.dynamic_query::<LOCKING>(filter));
311 for world in world.query::<'a, LOCKING, &World>() {
312 self.include(filter, world);
313 }
314 }
315}
316
317impl<'a, const LOCKING: bool> Iterator for MultiverseDynamicQueryIter<'a, LOCKING> {
318 type Item = DynamicQueryItem<'a>;
319
320 fn next(&mut self) -> Option<Self::Item> {
321 loop {
322 if let Some(query) = self.queries.back_mut() {
323 if let Some(result) = query.next() {
324 return Some(result);
325 }
326 self.queries.pop_back();
327 continue;
328 }
329 break;
330 }
331 None
332 }
333}
334
335pub struct MultiverseMultityTypedQueryIter<
336 'a,
337 const LOCKING: bool,
338 Fetch: TypedQueryFetch<'a, LOCKING>,
339> {
340 #[allow(clippy::type_complexity)]
342 queries: VecDeque<(
343 Option<Multity>,
344 TypedQueryIter<'a, LOCKING, (Entity, Fetch)>,
345 )>,
346}
347
348impl<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>> Default
349 for MultiverseMultityTypedQueryIter<'a, LOCKING, Fetch>
350{
351 fn default() -> Self {
352 Self {
353 queries: Default::default(),
354 }
355 }
356}
357
358impl<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>>
359 MultiverseMultityTypedQueryIter<'a, LOCKING, Fetch>
360{
361 pub fn new(world: &'a World) -> Self {
362 let mut result = Self::default();
363 result.include(world, None);
364 result
365 }
366
367 fn include(&mut self, world: &'a World, parent: Option<Multity>) {
368 self.queries.push_back((
369 parent.clone(),
370 world.query::<'a, LOCKING, (Entity, Fetch)>(),
371 ));
372 for (entity, world) in world.query::<'a, LOCKING, (Entity, &World)>() {
373 let parent = if let Some(parent) = parent.as_ref() {
374 parent.clone().with(entity)
375 } else {
376 Multity::new(entity)
377 };
378 self.include(world, Some(parent));
379 }
380 }
381}
382
383impl<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>> Iterator
384 for MultiverseMultityTypedQueryIter<'a, LOCKING, Fetch>
385{
386 type Item = (Multity, Fetch::Value);
387
388 fn next(&mut self) -> Option<Self::Item> {
389 loop {
390 if let Some((parent, query)) = self.queries.back_mut() {
391 if let Some((entity, result)) = query.next() {
392 let multity = if let Some(parent) = parent.as_ref() {
393 parent.clone().with(entity)
394 } else {
395 Multity::new(entity)
396 };
397 return Some((multity, result));
398 }
399 self.queries.pop_back();
400 continue;
401 }
402 break;
403 }
404 None
405 }
406}
407
408pub struct MultiverseMultityDynamicQueryIter<'a, const LOCKING: bool> {
409 queries: VecDeque<(Option<Multity>, DynamicQueryIter<'a, LOCKING>)>,
411}
412
413impl<const LOCKING: bool> Default for MultiverseMultityDynamicQueryIter<'_, LOCKING> {
414 fn default() -> Self {
415 Self {
416 queries: Default::default(),
417 }
418 }
419}
420
421impl<'a, const LOCKING: bool> MultiverseMultityDynamicQueryIter<'a, LOCKING> {
422 pub fn new(filter: &DynamicQueryFilter, world: &'a World) -> Self {
423 let mut result = Self::default();
424 result.include(filter, world, None);
425 result
426 }
427
428 fn include(&mut self, filter: &DynamicQueryFilter, world: &'a World, parent: Option<Multity>) {
429 self.queries
430 .push_back((parent.clone(), world.dynamic_query::<LOCKING>(filter)));
431 for (entity, world) in world.query::<'a, LOCKING, (Entity, &World)>() {
432 let parent = if let Some(parent) = parent.as_ref() {
433 parent.clone().with(entity)
434 } else {
435 Multity::new(entity)
436 };
437 self.include(filter, world, Some(parent));
438 }
439 }
440}
441
442impl<'a, const LOCKING: bool> Iterator for MultiverseMultityDynamicQueryIter<'a, LOCKING> {
443 type Item = (Multity, DynamicQueryItem<'a>);
444
445 fn next(&mut self) -> Option<Self::Item> {
446 loop {
447 if let Some((parent, query)) = self.queries.back_mut() {
448 if let Some(result) = query.next() {
449 let multity = if let Some(parent) = parent.as_ref() {
450 parent.clone().with(result.entity())
451 } else {
452 Multity::new(result.entity())
453 };
454 return Some((multity, result));
455 }
456 self.queries.pop_back();
457 continue;
458 }
459 break;
460 }
461 None
462 }
463}
464
465pub struct Multiverse<'a> {
466 pub world: &'a World,
467}
468
469impl<'a> Multiverse<'a> {
470 pub fn new(world: &'a World) -> Self {
471 Self { world }
472 }
473
474 pub fn component<const LOCKING: bool, T: Component>(
475 &self,
476 multity: Multity,
477 ) -> Result<HyperComponentRef<LOCKING, T>, WorldError> {
478 Ok(HyperComponentRef {
479 inner: self.get::<LOCKING, T>(multity, false)?,
480 })
481 }
482
483 pub fn component_mut<const LOCKING: bool, T: Component>(
484 &self,
485 multity: Multity,
486 ) -> Result<HyperComponentRefMut<LOCKING, T>, WorldError> {
487 Ok(HyperComponentRefMut {
488 inner: self.get::<LOCKING, T>(multity, true)?,
489 })
490 }
491
492 pub fn get<const LOCKING: bool, T: Component>(
493 &self,
494 multity: Multity,
495 unique: bool,
496 ) -> Result<ArchetypeMultityColumnAccess<'a, LOCKING, T>, WorldError> {
497 let mut worlds =
498 Vec::<ArchetypeEntityColumnAccess<LOCKING, World>>::with_capacity(multity.len());
499 let mut iter = multity.iter().peekable();
500 while let Some(entity) = iter.next() {
501 if iter.peek().is_none() {
502 let entity = if let Some(access) = worlds.last() {
503 let world =
504 unsafe { std::mem::transmute::<&World, &'a World>(access.read().unwrap()) };
505 world.get::<LOCKING, T>(entity, unique)?
506 } else {
507 self.world.get::<LOCKING, T>(entity, unique)?
508 };
509 return Ok(ArchetypeMultityColumnAccess {
510 _worlds: worlds,
511 entity,
512 });
513 }
514 let world = if let Some(access) = worlds.last() {
515 let world =
516 unsafe { std::mem::transmute::<&World, &'a World>(access.read().unwrap()) };
517 world.get::<LOCKING, World>(entity, unique)?
518 } else {
519 self.world.get::<LOCKING, World>(entity, unique)?
520 };
521 worlds.push(world);
522 }
523 unreachable!()
524 }
525
526 pub fn dynamic_get<const LOCKING: bool>(
527 &self,
528 type_hash: TypeHash,
529 multity: Multity,
530 unique: bool,
531 ) -> Result<ArchetypeDynamicMultityColumnAccess<LOCKING>, WorldError> {
532 let mut worlds =
533 Vec::<ArchetypeEntityColumnAccess<LOCKING, World>>::with_capacity(multity.len());
534 let mut iter = multity.iter().peekable();
535 while let Some(entity) = iter.next() {
536 if iter.peek().is_none() {
537 let entity = if let Some(access) = worlds.last() {
538 let world =
539 unsafe { std::mem::transmute::<&World, &'a World>(access.read().unwrap()) };
540 world.dynamic_get::<LOCKING>(type_hash, entity, unique)?
541 } else {
542 self.world
543 .dynamic_get::<LOCKING>(type_hash, entity, unique)?
544 };
545 return Ok(ArchetypeDynamicMultityColumnAccess {
546 _worlds: worlds,
547 entity,
548 });
549 }
550 let world = if let Some(access) = worlds.last() {
551 let world =
552 unsafe { std::mem::transmute::<&World, &'a World>(access.read().unwrap()) };
553 world.get::<LOCKING, World>(entity, unique)?
554 } else {
555 self.world.get::<LOCKING, World>(entity, unique)?
556 };
557 worlds.push(world);
558 }
559 unreachable!()
560 }
561
562 pub fn query<'b, const LOCKING: bool, Fetch: TypedQueryFetch<'b, LOCKING>>(
563 &'b self,
564 ) -> MultiverseTypedQueryIter<'b, LOCKING, Fetch> {
565 MultiverseTypedQueryIter::new(self.world)
566 }
567
568 pub fn multity_query<'b, const LOCKING: bool, Fetch: TypedQueryFetch<'b, LOCKING>>(
569 &'b self,
570 ) -> MultiverseMultityTypedQueryIter<'b, LOCKING, Fetch> {
571 MultiverseMultityTypedQueryIter::new(self.world)
572 }
573
574 pub fn dynamic_query<'b, const LOCKING: bool>(
575 &'b self,
576 filter: &DynamicQueryFilter,
577 ) -> MultiverseDynamicQueryIter<'a, LOCKING> {
578 MultiverseDynamicQueryIter::new(filter, self.world)
579 }
580
581 pub fn dynamic_multity_query<'b, const LOCKING: bool>(
582 &'b self,
583 filter: &DynamicQueryFilter,
584 ) -> MultiverseMultityDynamicQueryIter<'a, LOCKING> {
585 MultiverseMultityDynamicQueryIter::new(filter, self.world)
586 }
587}
588
589#[cfg(test)]
590mod tests {
591 use super::*;
592 use crate::{query::Include, world::World};
593
594 #[test]
595 fn test_multiverse() {
596 let mut world1 = World::default();
597 let a = world1.spawn((1usize,)).unwrap();
598 let b = world1.spawn((2usize,)).unwrap();
599 let c = world1.spawn((3usize,)).unwrap();
600
601 let mut world2 = World::default();
602 let d = world2.spawn((4usize,)).unwrap();
603 let e = world2.spawn((5usize,)).unwrap();
604 let f = world2.spawn((world1,)).unwrap();
605
606 let mut world3 = World::default();
607 let g = world3.spawn((6usize,)).unwrap();
608 let h = world3.spawn((world2,)).unwrap();
609
610 let mut world = World::default();
611 let i = world.spawn((world3,)).unwrap();
612
613 assert_eq!(
614 Multiverse::new(&world)
615 .query::<true, &usize>()
616 .copied()
617 .collect::<Vec<_>>(),
618 vec![1, 2, 3, 4, 5, 6]
619 );
620
621 assert_eq!(
622 Multiverse::new(&world)
623 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<usize>())
624 .map(|item| *item.read::<usize>().unwrap().read::<usize>().unwrap())
625 .collect::<Vec<_>>(),
626 vec![1, 2, 3, 4, 5, 6]
627 );
628
629 let multity = Multity::from_iter([i, h, f, b]);
630 *Multiverse::new(&world)
631 .component_mut::<true, usize>(multity.clone())
632 .unwrap() = 10;
633 assert_eq!(
634 *Multiverse::new(&world)
635 .component::<true, usize>(multity.clone())
636 .unwrap(),
637 10
638 );
639
640 assert_eq!(
641 Multiverse::new(&world)
642 .query::<true, &usize>()
643 .copied()
644 .collect::<Vec<_>>(),
645 vec![1, 10, 3, 4, 5, 6]
646 );
647
648 assert_eq!(
649 Multiverse::new(&world)
650 .multity_query::<true, Include<usize>>()
651 .map(|(multity, _)| multity)
652 .collect::<Vec<_>>(),
653 vec![
654 Multity::from_iter([i, h, f, a]),
655 Multity::from_iter([i, h, f, b]),
656 Multity::from_iter([i, h, f, c]),
657 Multity::from_iter([i, h, d]),
658 Multity::from_iter([i, h, e]),
659 Multity::from_iter([i, g]),
660 ]
661 );
662
663 assert_eq!(
664 Multiverse::new(&world)
665 .dynamic_multity_query::<true>(&DynamicQueryFilter::default().include::<usize>())
666 .map(|(multity, _)| multity)
667 .collect::<Vec<_>>(),
668 vec![
669 Multity::from_iter([i, h, f, a]),
670 Multity::from_iter([i, h, f, b]),
671 Multity::from_iter([i, h, f, c]),
672 Multity::from_iter([i, h, d]),
673 Multity::from_iter([i, h, e]),
674 Multity::from_iter([i, g]),
675 ]
676 );
677 }
678}