1use alloc::collections::{btree_set, BTreeSet};
2use core::{
3 hash::BuildHasher,
4 ops::{Deref, DerefMut},
5};
6
7use crate::entity::{Entity, EntityHashSet, EntityIndexSet};
8use alloc::vec::Vec;
9use indexmap::IndexSet;
10use smallvec::SmallVec;
11
12pub trait RelationshipSourceCollection {
15 type SourceIter<'a>: Iterator<Item = Entity>
23 where
24 Self: 'a;
25
26 fn new() -> Self;
28
29 fn with_capacity(capacity: usize) -> Self;
33
34 fn reserve(&mut self, additional: usize);
38
39 fn add(&mut self, entity: Entity) -> bool;
45
46 fn remove(&mut self, entity: Entity) -> bool;
51
52 fn iter(&self) -> Self::SourceIter<'_>;
54
55 fn len(&self) -> usize;
57
58 fn clear(&mut self);
60
61 fn shrink_to_fit(&mut self);
65
66 #[inline]
68 fn is_empty(&self) -> bool {
69 self.len() == 0
70 }
71
72 fn source_to_remove_before_add(&self) -> Option<Entity> {
75 None
76 }
77
78 fn extend_from_iter(&mut self, entities: impl IntoIterator<Item = Entity>);
82}
83
84pub trait OrderedRelationshipSourceCollection: RelationshipSourceCollection {
86 fn insert(&mut self, index: usize, entity: Entity);
89 fn remove_at(&mut self, index: usize) -> Option<Entity>;
91 fn insert_stable(&mut self, index: usize, entity: Entity);
95 fn remove_at_stable(&mut self, index: usize) -> Option<Entity>;
98 fn sort(&mut self);
100 fn insert_sorted(&mut self, entity: Entity);
102
103 fn place_most_recent(&mut self, index: usize);
105
106 fn place(&mut self, entity: Entity, index: usize);
110
111 fn push_front(&mut self, entity: Entity) {
113 self.insert(0, entity);
114 }
115
116 fn push_back(&mut self, entity: Entity) {
118 self.insert(usize::MAX, entity);
119 }
120
121 fn pop_front(&mut self) -> Option<Entity> {
123 self.remove_at(0)
124 }
125
126 fn pop_back(&mut self) -> Option<Entity> {
128 if self.is_empty() {
129 None
130 } else {
131 self.remove_at(self.len() - 1)
132 }
133 }
134}
135
136impl RelationshipSourceCollection for Vec<Entity> {
137 type SourceIter<'a> = core::iter::Copied<core::slice::Iter<'a, Entity>>;
138
139 fn new() -> Self {
140 Vec::new()
141 }
142
143 fn reserve(&mut self, additional: usize) {
144 Vec::reserve(self, additional);
145 }
146
147 fn with_capacity(capacity: usize) -> Self {
148 Vec::with_capacity(capacity)
149 }
150
151 fn add(&mut self, entity: Entity) -> bool {
152 Vec::push(self, entity);
153
154 true
155 }
156
157 fn remove(&mut self, entity: Entity) -> bool {
158 if let Some(index) = <[Entity]>::iter(self).position(|e| *e == entity) {
159 Vec::remove(self, index);
160 return true;
161 }
162
163 false
164 }
165
166 fn iter(&self) -> Self::SourceIter<'_> {
167 <[Entity]>::iter(self).copied()
168 }
169
170 fn len(&self) -> usize {
171 Vec::len(self)
172 }
173
174 fn clear(&mut self) {
175 self.clear();
176 }
177
178 fn shrink_to_fit(&mut self) {
179 Vec::shrink_to_fit(self);
180 }
181
182 fn extend_from_iter(&mut self, entities: impl IntoIterator<Item = Entity>) {
183 self.extend(entities);
184 }
185}
186
187impl OrderedRelationshipSourceCollection for Vec<Entity> {
188 fn insert(&mut self, index: usize, entity: Entity) {
189 self.push(entity);
190 let len = self.len();
191 if index < len {
192 self.swap(index, len - 1);
193 }
194 }
195
196 fn remove_at(&mut self, index: usize) -> Option<Entity> {
197 (index < self.len()).then(|| self.swap_remove(index))
198 }
199
200 fn insert_stable(&mut self, index: usize, entity: Entity) {
201 if index < self.len() {
202 Vec::insert(self, index, entity);
203 } else {
204 self.push(entity);
205 }
206 }
207
208 fn remove_at_stable(&mut self, index: usize) -> Option<Entity> {
209 (index < self.len()).then(|| self.remove(index))
210 }
211
212 fn sort(&mut self) {
213 self.sort_unstable();
214 }
215
216 fn insert_sorted(&mut self, entity: Entity) {
217 let index = self.partition_point(|e| e <= &entity);
218 self.insert_stable(index, entity);
219 }
220
221 fn place_most_recent(&mut self, index: usize) {
222 if let Some(entity) = self.pop() {
223 let index = index.min(self.len());
224 self.insert(index, entity);
225 }
226 }
227
228 fn place(&mut self, entity: Entity, index: usize) {
229 if let Some(current) = <[Entity]>::iter(self).position(|e| *e == entity) {
230 let index = index.min(self.len());
231 Vec::remove(self, current);
232 self.insert(index, entity);
233 };
234 }
235}
236
237impl RelationshipSourceCollection for EntityHashSet {
238 type SourceIter<'a> = core::iter::Copied<crate::entity::hash_set::Iter<'a>>;
239
240 fn new() -> Self {
241 EntityHashSet::new()
242 }
243
244 fn reserve(&mut self, additional: usize) {
245 self.0.reserve(additional);
246 }
247
248 fn with_capacity(capacity: usize) -> Self {
249 EntityHashSet::with_capacity(capacity)
250 }
251
252 fn add(&mut self, entity: Entity) -> bool {
253 self.insert(entity)
254 }
255
256 fn remove(&mut self, entity: Entity) -> bool {
257 self.0.remove(&entity)
260 }
261
262 fn iter(&self) -> Self::SourceIter<'_> {
263 self.iter().copied()
264 }
265
266 fn len(&self) -> usize {
267 self.len()
268 }
269
270 fn clear(&mut self) {
271 self.0.clear();
272 }
273
274 fn shrink_to_fit(&mut self) {
275 self.0.shrink_to_fit();
276 }
277
278 fn extend_from_iter(&mut self, entities: impl IntoIterator<Item = Entity>) {
279 self.extend(entities);
280 }
281}
282
283impl<const N: usize> RelationshipSourceCollection for SmallVec<[Entity; N]> {
284 type SourceIter<'a> = core::iter::Copied<core::slice::Iter<'a, Entity>>;
285
286 fn new() -> Self {
287 SmallVec::new()
288 }
289
290 fn reserve(&mut self, additional: usize) {
291 SmallVec::reserve(self, additional);
292 }
293
294 fn with_capacity(capacity: usize) -> Self {
295 SmallVec::with_capacity(capacity)
296 }
297
298 fn add(&mut self, entity: Entity) -> bool {
299 SmallVec::push(self, entity);
300
301 true
302 }
303
304 fn remove(&mut self, entity: Entity) -> bool {
305 if let Some(index) = <[Entity]>::iter(self).position(|e| *e == entity) {
306 SmallVec::remove(self, index);
307 return true;
308 }
309
310 false
311 }
312
313 fn iter(&self) -> Self::SourceIter<'_> {
314 <[Entity]>::iter(self).copied()
315 }
316
317 fn len(&self) -> usize {
318 SmallVec::len(self)
319 }
320
321 fn clear(&mut self) {
322 self.clear();
323 }
324
325 fn shrink_to_fit(&mut self) {
326 SmallVec::shrink_to_fit(self);
327 }
328
329 fn extend_from_iter(&mut self, entities: impl IntoIterator<Item = Entity>) {
330 self.extend(entities);
331 }
332}
333
334impl RelationshipSourceCollection for Entity {
335 type SourceIter<'a> = core::option::IntoIter<Entity>;
336
337 fn new() -> Self {
338 Entity::PLACEHOLDER
339 }
340
341 fn reserve(&mut self, _: usize) {}
342
343 fn with_capacity(_capacity: usize) -> Self {
344 Self::new()
345 }
346
347 fn add(&mut self, entity: Entity) -> bool {
348 *self = entity;
349 true
350 }
351
352 fn remove(&mut self, entity: Entity) -> bool {
353 if *self == entity {
354 *self = Entity::PLACEHOLDER;
355
356 return true;
357 }
358
359 false
360 }
361
362 fn iter(&self) -> Self::SourceIter<'_> {
363 if *self == Entity::PLACEHOLDER {
364 None.into_iter()
365 } else {
366 Some(*self).into_iter()
367 }
368 }
369
370 fn len(&self) -> usize {
371 if *self == Entity::PLACEHOLDER {
372 return 0;
373 }
374 1
375 }
376
377 fn clear(&mut self) {
378 *self = Entity::PLACEHOLDER;
379 }
380
381 fn shrink_to_fit(&mut self) {}
382
383 fn extend_from_iter(&mut self, entities: impl IntoIterator<Item = Entity>) {
384 for entity in entities {
385 *self = entity;
386 }
387 }
388
389 fn source_to_remove_before_add(&self) -> Option<Entity> {
390 if *self != Entity::PLACEHOLDER {
391 Some(*self)
392 } else {
393 None
394 }
395 }
396}
397
398impl<const N: usize> OrderedRelationshipSourceCollection for SmallVec<[Entity; N]> {
399 fn insert(&mut self, index: usize, entity: Entity) {
400 self.push(entity);
401 let len = self.len();
402 if index < len {
403 self.swap(index, len - 1);
404 }
405 }
406
407 fn remove_at(&mut self, index: usize) -> Option<Entity> {
408 (index < self.len()).then(|| self.swap_remove(index))
409 }
410
411 fn insert_stable(&mut self, index: usize, entity: Entity) {
412 if index < self.len() {
413 SmallVec::<[Entity; N]>::insert(self, index, entity);
414 } else {
415 self.push(entity);
416 }
417 }
418
419 fn remove_at_stable(&mut self, index: usize) -> Option<Entity> {
420 (index < self.len()).then(|| self.remove(index))
421 }
422
423 fn sort(&mut self) {
424 self.sort_unstable();
425 }
426
427 fn insert_sorted(&mut self, entity: Entity) {
428 let index = self.partition_point(|e| e <= &entity);
429 self.insert_stable(index, entity);
430 }
431
432 fn place_most_recent(&mut self, index: usize) {
433 if let Some(entity) = self.pop() {
434 let index = index.min(self.len() - 1);
435 self.insert(index, entity);
436 }
437 }
438
439 fn place(&mut self, entity: Entity, index: usize) {
440 if let Some(current) = <[Entity]>::iter(self).position(|e| *e == entity) {
441 let index = index.min(self.len() - 1);
443 SmallVec::<[Entity; N]>::remove(self, current);
444 self.insert(index, entity);
445 };
446 }
447}
448
449impl<S: BuildHasher + Default> RelationshipSourceCollection for IndexSet<Entity, S> {
450 type SourceIter<'a>
451 = core::iter::Copied<indexmap::set::Iter<'a, Entity>>
452 where
453 S: 'a;
454
455 fn new() -> Self {
456 IndexSet::default()
457 }
458
459 fn reserve(&mut self, additional: usize) {
460 self.reserve(additional);
461 }
462
463 fn with_capacity(capacity: usize) -> Self {
464 IndexSet::with_capacity_and_hasher(capacity, S::default())
465 }
466
467 fn add(&mut self, entity: Entity) -> bool {
468 self.insert(entity)
469 }
470
471 fn remove(&mut self, entity: Entity) -> bool {
472 self.shift_remove(&entity)
473 }
474
475 fn iter(&self) -> Self::SourceIter<'_> {
476 self.iter().copied()
477 }
478
479 fn len(&self) -> usize {
480 self.len()
481 }
482
483 fn clear(&mut self) {
484 self.clear();
485 }
486
487 fn shrink_to_fit(&mut self) {
488 self.shrink_to_fit();
489 }
490
491 fn extend_from_iter(&mut self, entities: impl IntoIterator<Item = Entity>) {
492 self.extend(entities);
493 }
494}
495
496impl RelationshipSourceCollection for EntityIndexSet {
497 type SourceIter<'a> = core::iter::Copied<crate::entity::index_set::Iter<'a>>;
498
499 fn new() -> Self {
500 EntityIndexSet::new()
501 }
502
503 fn reserve(&mut self, additional: usize) {
504 self.deref_mut().reserve(additional);
505 }
506
507 fn with_capacity(capacity: usize) -> Self {
508 EntityIndexSet::with_capacity(capacity)
509 }
510
511 fn add(&mut self, entity: Entity) -> bool {
512 self.insert(entity)
513 }
514
515 fn remove(&mut self, entity: Entity) -> bool {
516 self.deref_mut().shift_remove(&entity)
517 }
518
519 fn iter(&self) -> Self::SourceIter<'_> {
520 self.iter().copied()
521 }
522
523 fn len(&self) -> usize {
524 self.deref().len()
525 }
526
527 fn clear(&mut self) {
528 self.deref_mut().clear();
529 }
530
531 fn shrink_to_fit(&mut self) {
532 self.deref_mut().shrink_to_fit();
533 }
534
535 fn extend_from_iter(&mut self, entities: impl IntoIterator<Item = Entity>) {
536 self.extend(entities);
537 }
538}
539
540impl RelationshipSourceCollection for BTreeSet<Entity> {
541 type SourceIter<'a> = core::iter::Copied<btree_set::Iter<'a, Entity>>;
542
543 fn new() -> Self {
544 BTreeSet::new()
545 }
546
547 fn with_capacity(_: usize) -> Self {
548 Self::new()
550 }
551
552 fn reserve(&mut self, _: usize) {
553 }
555
556 fn add(&mut self, entity: Entity) -> bool {
557 self.insert(entity)
558 }
559
560 fn remove(&mut self, entity: Entity) -> bool {
561 self.remove(&entity)
562 }
563
564 fn iter(&self) -> Self::SourceIter<'_> {
565 self.iter().copied()
566 }
567
568 fn len(&self) -> usize {
569 self.len()
570 }
571
572 fn clear(&mut self) {
573 self.clear();
574 }
575
576 fn shrink_to_fit(&mut self) {
577 }
579
580 fn extend_from_iter(&mut self, entities: impl IntoIterator<Item = Entity>) {
581 self.extend(entities);
582 }
583}
584
585#[cfg(test)]
586mod tests {
587 use super::*;
588 use crate::prelude::{Component, World};
589 use crate::relationship::RelationshipTarget;
590
591 #[test]
592 fn vec_relationship_source_collection() {
593 #[derive(Component)]
594 #[relationship(relationship_target = RelTarget)]
595 struct Rel(Entity);
596
597 #[derive(Component)]
598 #[relationship_target(relationship = Rel, linked_spawn)]
599 struct RelTarget(Vec<Entity>);
600
601 let mut world = World::new();
602 let a = world.spawn_empty().id();
603 let b = world.spawn_empty().id();
604
605 world.entity_mut(a).insert(Rel(b));
606
607 let rel_target = world.get::<RelTarget>(b).unwrap();
608 let collection = rel_target.collection();
609 assert_eq!(collection, &alloc::vec!(a));
610 }
611
612 #[test]
613 fn smallvec_relationship_source_collection() {
614 #[derive(Component)]
615 #[relationship(relationship_target = RelTarget)]
616 struct Rel(Entity);
617
618 #[derive(Component)]
619 #[relationship_target(relationship = Rel, linked_spawn)]
620 struct RelTarget(SmallVec<[Entity; 4]>);
621
622 let mut world = World::new();
623 let a = world.spawn_empty().id();
624 let b = world.spawn_empty().id();
625
626 world.entity_mut(a).insert(Rel(b));
627
628 let rel_target = world.get::<RelTarget>(b).unwrap();
629 let collection = rel_target.collection();
630 assert_eq!(collection, &SmallVec::from_buf([a]));
631 }
632
633 #[test]
634 fn entity_relationship_source_collection() {
635 #[derive(Component)]
636 #[relationship(relationship_target = RelTarget)]
637 struct Rel(Entity);
638
639 #[derive(Component)]
640 #[relationship_target(relationship = Rel)]
641 struct RelTarget(Entity);
642
643 let mut world = World::new();
644 let a = world.spawn_empty().id();
645 let b = world.spawn_empty().id();
646
647 world.entity_mut(a).insert(Rel(b));
648
649 let rel_target = world.get::<RelTarget>(b).unwrap();
650 let collection = rel_target.collection();
651 assert_eq!(collection, &a);
652 }
653
654 #[test]
655 fn one_to_one_relationships() {
656 #[derive(Component)]
657 #[relationship(relationship_target = Below)]
658 struct Above(Entity);
659
660 #[derive(Component)]
661 #[relationship_target(relationship = Above)]
662 struct Below(Entity);
663
664 let mut world = World::new();
665 let a = world.spawn_empty().id();
666 let b = world.spawn_empty().id();
667
668 world.entity_mut(a).insert(Above(b));
669 assert_eq!(a, world.get::<Below>(b).unwrap().0);
670
671 world.entity_mut(b).remove::<Below>();
673 assert!(world.get::<Above>(a).is_none());
674
675 world.entity_mut(a).insert(Above(b));
677 world.entity_mut(a).remove::<Above>();
678 assert!(world.get::<Below>(b).is_none());
679
680 let c = world.spawn_empty().id();
682 world.entity_mut(a).insert(Above(c));
683 assert!(world.get::<Below>(b).is_none());
684 assert_eq!(a, world.get::<Below>(c).unwrap().0);
685 }
686
687 #[test]
688 fn entity_index_map() {
689 for add_before in [false, true] {
690 #[derive(Component)]
691 #[relationship(relationship_target = RelTarget)]
692 struct Rel(Entity);
693
694 #[derive(Component)]
695 #[relationship_target(relationship = Rel, linked_spawn)]
696 struct RelTarget(Vec<Entity>);
697
698 let mut world = World::new();
699 if add_before {
700 let _ = world.spawn_empty().id();
701 }
702 let a = world.spawn_empty().id();
703 let b = world.spawn_empty().id();
704 let c = world.spawn_empty().id();
705 let d = world.spawn_empty().id();
706
707 world.entity_mut(a).add_related::<Rel>(&[b, c, d]);
708
709 let rel_target = world.get::<RelTarget>(a).unwrap();
710 let collection = rel_target.collection();
711
712 assert!(collection.iter().eq([b, c, d]));
714
715 world.entity_mut(c).despawn();
716
717 let rel_target = world.get::<RelTarget>(a).unwrap();
718 let collection = rel_target.collection();
719
720 assert!(collection.iter().eq([b, d]));
722 }
723 }
724
725 #[test]
726 fn one_to_one_relationship_shared_target() {
727 #[derive(Component)]
728 #[relationship(relationship_target = Below)]
729 struct Above(Entity);
730
731 #[derive(Component)]
732 #[relationship_target(relationship = Above)]
733 struct Below(Entity);
734 let mut world = World::new();
735 let a = world.spawn_empty().id();
736 let b = world.spawn_empty().id();
737 let c = world.spawn_empty().id();
738
739 world.entity_mut(a).insert(Above(c));
740 world.entity_mut(b).insert(Above(c));
741
742 assert!(
744 world.get::<Above>(a).is_none(),
745 "Original relationship should be removed"
746 );
747 assert_eq!(
748 world.get::<Above>(b).unwrap().0,
749 c,
750 "New relationship should be established"
751 );
752 assert_eq!(
753 world.get::<Below>(c).unwrap().0,
754 b,
755 "Target should point to new source"
756 );
757 }
758
759 #[test]
760 fn one_to_one_relationship_reinsert() {
761 #[derive(Component)]
762 #[relationship(relationship_target = Below)]
763 struct Above(Entity);
764
765 #[derive(Component)]
766 #[relationship_target(relationship = Above)]
767 struct Below(Entity);
768
769 let mut world = World::new();
770 let a = world.spawn_empty().id();
771 let b = world.spawn_empty().id();
772
773 world.entity_mut(a).insert(Above(b));
774 world.entity_mut(a).insert(Above(b));
775 }
776}