Expand the RelationshipSourceCollection to return more information (#18241)

# Objective

While redoing #18058 I needed `RelationshipSourceCollection` (henceforth
referred to as the **Trait**) to implement `clear` so I added it.

## Solution

Add the `clear` method to the **Trait**.
Also make `add` and `remove` report if they succeeded.

## Testing

Eyeballs

---

## Showcase

The `RelationshipSourceCollection` trait now reports if adding or
removing an entity from it was successful.
It also not contains the `clear` method so you can easily clear the
collection in generic contexts.

## Changes

EDITED by Alice: We should get this into 0.16, so no migration guide
needed.

The `RelationshipSourceCollection` methods `add` and `remove` now need
to return a boolean indicating if they were successful (adding a entity
to a set that already contains it counts as failure). Additionally the
`clear` method has been added to support clearing the collection in
generic contexts.
This commit is contained in:
Brezak 2025-03-10 23:04:08 +01:00 committed by GitHub
parent ed529a7cae
commit 906d788420
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -20,10 +20,17 @@ pub trait RelationshipSourceCollection {
fn with_capacity(capacity: usize) -> Self;
/// Adds the given `entity` to the collection.
fn add(&mut self, entity: Entity);
///
/// Returns whether the entity was added to the collection.
/// Mainly useful when dealing with collections that don't allow
/// multiple instances of the same entity ([`EntityHashSet`]).
fn add(&mut self, entity: Entity) -> bool;
/// Removes the given `entity` from the collection.
fn remove(&mut self, entity: Entity);
///
/// Returns whether the collection actually contained
/// the entity.
fn remove(&mut self, entity: Entity) -> bool;
/// Iterates all entities in the collection.
fn iter(&self) -> Self::SourceIter<'_>;
@ -31,6 +38,9 @@ pub trait RelationshipSourceCollection {
/// Returns the current length of the collection.
fn len(&self) -> usize;
/// Clears the collection.
fn clear(&mut self);
/// Returns true if the collection contains no entities.
#[inline]
fn is_empty(&self) -> bool {
@ -45,14 +55,20 @@ impl RelationshipSourceCollection for Vec<Entity> {
Vec::with_capacity(capacity)
}
fn add(&mut self, entity: Entity) {
fn add(&mut self, entity: Entity) -> bool {
Vec::push(self, entity);
true
}
fn remove(&mut self, entity: Entity) {
fn remove(&mut self, entity: Entity) -> bool {
if let Some(index) = <[Entity]>::iter(self).position(|e| *e == entity) {
Vec::remove(self, index);
return true;
}
false
}
fn iter(&self) -> Self::SourceIter<'_> {
@ -62,6 +78,10 @@ impl RelationshipSourceCollection for Vec<Entity> {
fn len(&self) -> usize {
Vec::len(self)
}
fn clear(&mut self) {
self.clear();
}
}
impl RelationshipSourceCollection for EntityHashSet {
@ -71,14 +91,14 @@ impl RelationshipSourceCollection for EntityHashSet {
EntityHashSet::with_capacity(capacity)
}
fn add(&mut self, entity: Entity) {
self.insert(entity);
fn add(&mut self, entity: Entity) -> bool {
self.insert(entity)
}
fn remove(&mut self, entity: Entity) {
fn remove(&mut self, entity: Entity) -> bool {
// We need to call the remove method on the underlying hash set,
// which takes its argument by reference
self.0.remove(&entity);
self.0.remove(&entity)
}
fn iter(&self) -> Self::SourceIter<'_> {
@ -88,6 +108,10 @@ impl RelationshipSourceCollection for EntityHashSet {
fn len(&self) -> usize {
self.len()
}
fn clear(&mut self) {
self.0.clear();
}
}
impl<const N: usize> RelationshipSourceCollection for SmallVec<[Entity; N]> {
@ -97,14 +121,20 @@ impl<const N: usize> RelationshipSourceCollection for SmallVec<[Entity; N]> {
SmallVec::with_capacity(capacity)
}
fn add(&mut self, entity: Entity) {
fn add(&mut self, entity: Entity) -> bool {
SmallVec::push(self, entity);
true
}
fn remove(&mut self, entity: Entity) {
fn remove(&mut self, entity: Entity) -> bool {
if let Some(index) = <[Entity]>::iter(self).position(|e| *e == entity) {
SmallVec::remove(self, index);
return true;
}
false
}
fn iter(&self) -> Self::SourceIter<'_> {
@ -114,6 +144,10 @@ impl<const N: usize> RelationshipSourceCollection for SmallVec<[Entity; N]> {
fn len(&self) -> usize {
SmallVec::len(self)
}
fn clear(&mut self) {
self.clear();
}
}
impl RelationshipSourceCollection for Entity {
@ -123,14 +157,20 @@ impl RelationshipSourceCollection for Entity {
Entity::PLACEHOLDER
}
fn add(&mut self, entity: Entity) {
fn add(&mut self, entity: Entity) -> bool {
*self = entity;
true
}
fn remove(&mut self, entity: Entity) {
fn remove(&mut self, entity: Entity) -> bool {
if *self == entity {
*self = Entity::PLACEHOLDER;
return true;
}
false
}
fn iter(&self) -> Self::SourceIter<'_> {
@ -143,6 +183,10 @@ impl RelationshipSourceCollection for Entity {
}
1
}
fn clear(&mut self) {
*self = Entity::PLACEHOLDER;
}
}
#[cfg(test)]