Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions crates/bevy_ecs/src/entity/remote_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl Chunk {
let head = self.first.load(Ordering::Relaxed);

// SAFETY: Caller ensures we are init, so the chunk was allocated via a `Vec` and the index is within the capacity.
unsafe { core::slice::from_raw_parts(head, len) }
unsafe { core::slice::from_raw_parts(head.add(index as usize), len) }
}

/// Sets this entity at this index.
Expand Down Expand Up @@ -339,7 +339,10 @@ impl<'a> Iterator for FreeBufferIterator<'a> {
}

let still_need = self.future_buffer_indices.len() as u32;
let next_index = self.future_buffer_indices.next()?;
if still_need == 0 {
return None;
}
let next_index = self.future_buffer_indices.start;
let (chunk, index, chunk_capacity) = self.buffer.index_in_chunk(next_index);

// SAFETY: Assured by `FreeBuffer::iter`
Expand Down Expand Up @@ -1115,4 +1118,32 @@ mod tests {
entities.dedup();
assert_eq!(pre_len, entities.len());
}

/// Bevy's allocator doesn't make guarantees about what order entities will be allocated in.
/// This test just exists to make sure allocations don't step on each other's toes.
#[test]
fn allocation_order_correctness() {
let mut allocator = Allocator::new();
let e0 = allocator.alloc();
let e1 = allocator.alloc();
let e2 = allocator.alloc();
let e3 = allocator.alloc();
allocator.free(e0);
allocator.free(e1);
allocator.free(e2);
allocator.free(e3);

let r0 = allocator.alloc();
let mut many = allocator.alloc_many(2);
let r1 = many.next().unwrap();
let r2 = many.next().unwrap();
assert!(many.next().is_none());
drop(many);
let r3 = allocator.alloc();

assert_eq!(r0, e3);
assert_eq!(r1, e1);
assert_eq!(r2, e2);
assert_eq!(r3, e0);
}
}