1
1
use alloc:: collections:: { btree_set, BTreeSet } ;
2
+ use core:: {
3
+ hash:: BuildHasher ,
4
+ ops:: { Deref , DerefMut } ,
5
+ } ;
2
6
3
- use crate :: entity:: { hash_set :: EntityHashSet , Entity } ;
7
+ use crate :: entity:: { Entity , EntityHashSet , EntityIndexSet } ;
4
8
use alloc:: vec:: Vec ;
9
+ use indexmap:: IndexSet ;
5
10
use smallvec:: SmallVec ;
6
11
7
12
/// The internal [`Entity`] collection used by a [`RelationshipTarget`](crate::relationship::RelationshipTarget) component.
@@ -447,6 +452,97 @@ impl<const N: usize> OrderedRelationshipSourceCollection for SmallVec<[Entity; N
447
452
}
448
453
}
449
454
455
+ impl < S : BuildHasher + Default > RelationshipSourceCollection for IndexSet < Entity , S > {
456
+ type SourceIter < ' a >
457
+ = core:: iter:: Copied < indexmap:: set:: Iter < ' a , Entity > >
458
+ where
459
+ S : ' a ;
460
+
461
+ fn new ( ) -> Self {
462
+ IndexSet :: default ( )
463
+ }
464
+
465
+ fn reserve ( & mut self , additional : usize ) {
466
+ self . reserve ( additional) ;
467
+ }
468
+
469
+ fn with_capacity ( capacity : usize ) -> Self {
470
+ IndexSet :: with_capacity_and_hasher ( capacity, S :: default ( ) )
471
+ }
472
+
473
+ fn add ( & mut self , entity : Entity ) -> bool {
474
+ self . insert ( entity)
475
+ }
476
+
477
+ fn remove ( & mut self , entity : Entity ) -> bool {
478
+ self . shift_remove ( & entity)
479
+ }
480
+
481
+ fn iter ( & self ) -> Self :: SourceIter < ' _ > {
482
+ self . iter ( ) . copied ( )
483
+ }
484
+
485
+ fn len ( & self ) -> usize {
486
+ self . len ( )
487
+ }
488
+
489
+ fn clear ( & mut self ) {
490
+ self . clear ( ) ;
491
+ }
492
+
493
+ fn shrink_to_fit ( & mut self ) {
494
+ self . shrink_to_fit ( ) ;
495
+ }
496
+
497
+ fn extend_from_iter ( & mut self , entities : impl IntoIterator < Item = Entity > ) {
498
+ self . extend ( entities) ;
499
+ }
500
+ }
501
+
502
+ impl RelationshipSourceCollection for EntityIndexSet {
503
+ type SourceIter < ' a > = core:: iter:: Copied < crate :: entity:: index_set:: Iter < ' a > > ;
504
+
505
+ fn new ( ) -> Self {
506
+ EntityIndexSet :: new ( )
507
+ }
508
+
509
+ fn reserve ( & mut self , additional : usize ) {
510
+ self . deref_mut ( ) . reserve ( additional) ;
511
+ }
512
+
513
+ fn with_capacity ( capacity : usize ) -> Self {
514
+ EntityIndexSet :: with_capacity ( capacity)
515
+ }
516
+
517
+ fn add ( & mut self , entity : Entity ) -> bool {
518
+ self . insert ( entity)
519
+ }
520
+
521
+ fn remove ( & mut self , entity : Entity ) -> bool {
522
+ self . deref_mut ( ) . shift_remove ( & entity)
523
+ }
524
+
525
+ fn iter ( & self ) -> Self :: SourceIter < ' _ > {
526
+ self . iter ( ) . copied ( )
527
+ }
528
+
529
+ fn len ( & self ) -> usize {
530
+ self . deref ( ) . len ( )
531
+ }
532
+
533
+ fn clear ( & mut self ) {
534
+ self . deref_mut ( ) . clear ( ) ;
535
+ }
536
+
537
+ fn shrink_to_fit ( & mut self ) {
538
+ self . deref_mut ( ) . shrink_to_fit ( ) ;
539
+ }
540
+
541
+ fn extend_from_iter ( & mut self , entities : impl IntoIterator < Item = Entity > ) {
542
+ self . extend ( entities) ;
543
+ }
544
+ }
545
+
450
546
impl RelationshipSourceCollection for BTreeSet < Entity > {
451
547
type SourceIter < ' a > = core:: iter:: Copied < btree_set:: Iter < ' a , Entity > > ;
452
548
@@ -590,6 +686,40 @@ mod tests {
590
686
assert_eq ! ( a, world. get:: <Below >( c) . unwrap( ) . 0 ) ;
591
687
}
592
688
689
+ #[ test]
690
+ fn entity_index_map ( ) {
691
+ #[ derive( Component ) ]
692
+ #[ relationship( relationship_target = RelTarget ) ]
693
+ struct Rel ( Entity ) ;
694
+
695
+ #[ derive( Component ) ]
696
+ #[ relationship_target( relationship = Rel , linked_spawn) ]
697
+ struct RelTarget ( EntityHashSet ) ;
698
+
699
+ let mut world = World :: new ( ) ;
700
+ let a = world. spawn_empty ( ) . id ( ) ;
701
+ let b = world. spawn_empty ( ) . id ( ) ;
702
+ let c = world. spawn_empty ( ) . id ( ) ;
703
+
704
+ let d = world. spawn_empty ( ) . id ( ) ;
705
+
706
+ world. entity_mut ( a) . add_related :: < Rel > ( & [ b, c, d] ) ;
707
+
708
+ let rel_target = world. get :: < RelTarget > ( a) . unwrap ( ) ;
709
+ let collection = rel_target. collection ( ) ;
710
+
711
+ // Insertions should maintain ordering
712
+ assert ! ( collection. iter( ) . eq( & [ b, c, d] ) ) ;
713
+
714
+ world. entity_mut ( c) . despawn ( ) ;
715
+
716
+ let rel_target = world. get :: < RelTarget > ( a) . unwrap ( ) ;
717
+ let collection = rel_target. collection ( ) ;
718
+
719
+ // Removals should maintain ordering
720
+ assert ! ( collection. iter( ) . eq( & [ b, d] ) ) ;
721
+ }
722
+
593
723
#[ test]
594
724
#[ should_panic]
595
725
fn one_to_one_relationship_shared_target ( ) {
@@ -600,7 +730,6 @@ mod tests {
600
730
#[ derive( Component ) ]
601
731
#[ relationship_target( relationship = Above ) ]
602
732
struct Below ( Entity ) ;
603
-
604
733
let mut world = World :: new ( ) ;
605
734
let a = world. spawn_empty ( ) . id ( ) ;
606
735
let b = world. spawn_empty ( ) . id ( ) ;
0 commit comments