fix .insert_related index bound (#19134)

# Objective

resolves #19092

## Solution

- remove the `.saturating_sub` from the index transformation
- add `.saturating_add` to the internal offset calculation

## Testing

- added regression test, confirming 0 index order + testing max bound
This commit is contained in:
databasedav 2025-05-09 10:10:54 -07:00 committed by GitHub
parent 732b2e0c79
commit 95470df3c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 4 deletions

View File

@ -633,6 +633,43 @@ mod tests {
);
}
// regression test for https://github.com/bevyengine/bevy/pull/19134
#[test]
fn insert_children_index_bound() {
let mut world = World::new();
let child1 = world.spawn_empty().id();
let child2 = world.spawn_empty().id();
let child3 = world.spawn_empty().id();
let child4 = world.spawn_empty().id();
let mut entity_world_mut = world.spawn_empty();
let first_children = entity_world_mut.add_children(&[child1, child2]).id();
let hierarchy = get_hierarchy(&world, first_children);
assert_eq!(
hierarchy,
Node::new_with(first_children, vec![Node::new(child1), Node::new(child2)])
);
let root = world
.entity_mut(first_children)
.insert_children(usize::MAX, &[child3, child4])
.id();
let hierarchy = get_hierarchy(&world, root);
assert_eq!(
hierarchy,
Node::new_with(
root,
vec![
Node::new(child1),
Node::new(child2),
Node::new(child3),
Node::new(child4),
]
)
);
}
#[test]
fn remove_children() {
let mut world = World::new();

View File

@ -86,7 +86,7 @@ impl<'w> EntityWorldMut<'w> {
let id = self.id();
self.world_scope(|world| {
for (offset, related) in related.iter().enumerate() {
let index = index + offset;
let index = index.saturating_add(offset);
if world
.get::<R>(*related)
.is_some_and(|relationship| relationship.get() == id)

View File

@ -220,15 +220,14 @@ impl OrderedRelationshipSourceCollection for Vec<Entity> {
fn place_most_recent(&mut self, index: usize) {
if let Some(entity) = self.pop() {
let index = index.min(self.len().saturating_sub(1));
let index = index.min(self.len());
self.insert(index, entity);
}
}
fn place(&mut self, entity: Entity, index: usize) {
if let Some(current) = <[Entity]>::iter(self).position(|e| *e == entity) {
// The len is at least 1, so the subtraction is safe.
let index = index.min(self.len().saturating_sub(1));
let index = index.min(self.len());
Vec::remove(self, current);
self.insert(index, entity);
};