Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/relationship/relationship_source_collection.rs
6600 views
1
use alloc::collections::{btree_set, BTreeSet};
2
use core::{
3
hash::BuildHasher,
4
ops::{Deref, DerefMut},
5
};
6
7
use crate::entity::{Entity, EntityHashSet, EntityIndexSet};
8
use alloc::vec::Vec;
9
use indexmap::IndexSet;
10
use smallvec::SmallVec;
11
12
/// The internal [`Entity`] collection used by a [`RelationshipTarget`](crate::relationship::RelationshipTarget) component.
13
/// This is not intended to be modified directly by users, as it could invalidate the correctness of relationships.
14
pub trait RelationshipSourceCollection {
15
/// The type of iterator returned by the `iter` method.
16
///
17
/// This is an associated type (rather than using a method that returns an opaque return-position impl trait)
18
/// to ensure that all methods and traits (like [`DoubleEndedIterator`]) of the underlying collection's iterator
19
/// are available to the user when implemented without unduly restricting the possible collections.
20
///
21
/// The [`SourceIter`](super::SourceIter) type alias can be helpful to reduce confusion when working with this associated type.
22
type SourceIter<'a>: Iterator<Item = Entity>
23
where
24
Self: 'a;
25
26
/// Creates a new empty instance.
27
fn new() -> Self;
28
29
/// Returns an instance with the given pre-allocated entity `capacity`.
30
///
31
/// Some collections will ignore the provided `capacity` and return a default instance.
32
fn with_capacity(capacity: usize) -> Self;
33
34
/// Reserves capacity for at least `additional` more entities to be inserted.
35
///
36
/// Not all collections support this operation, in which case it is a no-op.
37
fn reserve(&mut self, additional: usize);
38
39
/// Adds the given `entity` to the collection.
40
///
41
/// Returns whether the entity was added to the collection.
42
/// Mainly useful when dealing with collections that don't allow
43
/// multiple instances of the same entity ([`EntityHashSet`]).
44
fn add(&mut self, entity: Entity) -> bool;
45
46
/// Removes the given `entity` from the collection.
47
///
48
/// Returns whether the collection actually contained
49
/// the entity.
50
fn remove(&mut self, entity: Entity) -> bool;
51
52
/// Iterates all entities in the collection.
53
fn iter(&self) -> Self::SourceIter<'_>;
54
55
/// Returns the current length of the collection.
56
fn len(&self) -> usize;
57
58
/// Clears the collection.
59
fn clear(&mut self);
60
61
/// Attempts to save memory by shrinking the capacity to fit the current length.
62
///
63
/// This operation is a no-op for collections that do not support it.
64
fn shrink_to_fit(&mut self);
65
66
/// Returns true if the collection contains no entities.
67
#[inline]
68
fn is_empty(&self) -> bool {
69
self.len() == 0
70
}
71
72
/// For one-to-one relationships, returns the entity that should be removed before adding a new one.
73
/// Returns `None` for one-to-many relationships or when no entity needs to be removed.
74
fn source_to_remove_before_add(&self) -> Option<Entity> {
75
None
76
}
77
78
/// Add multiple entities to collection at once.
79
///
80
/// May be faster than repeatedly calling [`Self::add`].
81
fn extend_from_iter(&mut self, entities: impl IntoIterator<Item = Entity>);
82
}
83
84
/// This trait signals that a [`RelationshipSourceCollection`] is ordered.
85
pub trait OrderedRelationshipSourceCollection: RelationshipSourceCollection {
86
/// Inserts the entity at a specific index.
87
/// If the index is too large, the entity will be added to the end of the collection.
88
fn insert(&mut self, index: usize, entity: Entity);
89
/// Removes the entity at the specified index if it exists.
90
fn remove_at(&mut self, index: usize) -> Option<Entity>;
91
/// Inserts the entity at a specific index.
92
/// This will never reorder other entities.
93
/// If the index is too large, the entity will be added to the end of the collection.
94
fn insert_stable(&mut self, index: usize, entity: Entity);
95
/// Removes the entity at the specified index if it exists.
96
/// This will never reorder other entities.
97
fn remove_at_stable(&mut self, index: usize) -> Option<Entity>;
98
/// Sorts the source collection.
99
fn sort(&mut self);
100
/// Inserts the entity at the proper place to maintain sorting.
101
fn insert_sorted(&mut self, entity: Entity);
102
103
/// This places the most recently added entity at the particular index.
104
fn place_most_recent(&mut self, index: usize);
105
106
/// This places the given entity at the particular index.
107
/// This will do nothing if the entity is not in the collection.
108
/// If the index is out of bounds, this will put the entity at the end.
109
fn place(&mut self, entity: Entity, index: usize);
110
111
/// Adds the entity at index 0.
112
fn push_front(&mut self, entity: Entity) {
113
self.insert(0, entity);
114
}
115
116
/// Adds the entity to the back of the collection.
117
fn push_back(&mut self, entity: Entity) {
118
self.insert(usize::MAX, entity);
119
}
120
121
/// Removes the first entity.
122
fn pop_front(&mut self) -> Option<Entity> {
123
self.remove_at(0)
124
}
125
126
/// Removes the last entity.
127
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
136
impl 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
187
impl 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
237
impl 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
// We need to call the remove method on the underlying hash set,
258
// which takes its argument by reference
259
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
283
impl<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
334
impl 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
398
impl<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
// The len is at least 1, so the subtraction is safe.
442
let index = index.min(self.len() - 1);
443
SmallVec::<[Entity; N]>::remove(self, current);
444
self.insert(index, entity);
445
};
446
}
447
}
448
449
impl<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
496
impl 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
540
impl 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
// BTreeSet doesn't have a capacity
549
Self::new()
550
}
551
552
fn reserve(&mut self, _: usize) {
553
// BTreeSet doesn't have a capacity
554
}
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
// BTreeSet doesn't have a capacity
578
}
579
580
fn extend_from_iter(&mut self, entities: impl IntoIterator<Item = Entity>) {
581
self.extend(entities);
582
}
583
}
584
585
#[cfg(test)]
586
mod 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
// Verify removing target removes relationship
672
world.entity_mut(b).remove::<Below>();
673
assert!(world.get::<Above>(a).is_none());
674
675
// Verify removing relationship removes target
676
world.entity_mut(a).insert(Above(b));
677
world.entity_mut(a).remove::<Above>();
678
assert!(world.get::<Below>(b).is_none());
679
680
// Actually - a is above c now! Verify relationship was updated correctly
681
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
// Insertions should maintain ordering
713
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
// Removals should maintain ordering
721
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
// The original relationship (a -> c) should be removed and the new relationship (b -> c) should be established
743
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
}
777
778