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

View File

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