use bulk allocator

This commit is contained in:
Elliott Pierce 2025-05-30 23:52:41 -04:00
parent 5c582666be
commit 01d6785f2d
2 changed files with 21 additions and 6 deletions

View File

@ -14,7 +14,7 @@ use crate::{
Component, ComponentId, Components, ComponentsRegistrator, RequiredComponentConstructor,
RequiredComponents, StorageType, Tick,
},
entity::{Entities, Entity, EntityLocation},
entity::{Entities, EntitiesAllocator, Entity, EntityLocation},
observer::Observers,
prelude::World,
query::DebugCheckedUnwrap,
@ -1782,6 +1782,12 @@ impl<'w> BundleSpawner<'w> {
(location, after_effect)
}
#[inline]
pub fn allocator(&self) -> &'w EntitiesAllocator {
// SAFETY: No outstanding references to self.world, changes to allocator cannot invalidate our internal pointers
unsafe { &self.world.world().allocator }
}
/// # Safety
/// `T` must match this [`BundleInfo`]'s type
#[inline]
@ -1790,8 +1796,7 @@ impl<'w> BundleSpawner<'w> {
bundle: T,
caller: MaybeLocation,
) -> (Entity, T::Effect) {
// SAFETY: No outstanding references to self.world, changes to entities cannot invalidate our internal pointers
let entity = unsafe { self.world.world().allocator.alloc() };
let entity = self.allocator().alloc();
// SAFETY: entity is allocated (but non-existent), `T` matches this BundleInfo's type
let (_, after_effect) = unsafe { self.construct(entity, bundle, caller) };
(entity, after_effect)

View File

@ -1,7 +1,7 @@
use crate::{
bundle::{Bundle, BundleSpawner, NoBundleEffect},
change_detection::MaybeLocation,
entity::{Entity, EntitySetIterator},
entity::{AllocEntitiesIterator, Entity, EntitySetIterator},
world::World,
};
use core::iter::FusedIterator;
@ -17,6 +17,7 @@ where
{
inner: I,
spawner: BundleSpawner<'w>,
allocator: AllocEntitiesIterator<'w>,
caller: MaybeLocation,
}
@ -42,6 +43,7 @@ where
Self {
inner: iter,
allocator: spawner.allocator().alloc_many(length as u32),
spawner,
caller,
}
@ -71,8 +73,16 @@ where
fn next(&mut self) -> Option<Entity> {
let bundle = self.inner.next()?;
// SAFETY: bundle matches spawner type
unsafe { Some(self.spawner.spawn(bundle, self.caller).0) }
Some(if let Some(bulk) = self.allocator.next() {
// SAFETY: bundle matches spawner type and we just allocated it
unsafe {
self.spawner.construct(bulk, bundle, self.caller);
}
bulk
} else {
// SAFETY: bundle matches spawner type
unsafe { self.spawner.spawn(bundle, self.caller).0 }
})
}
fn size_hint(&self) -> (usize, Option<usize>) {