Path: blob/main/crates/bevy_ecs/src/world/spawn_batch.rs
6604 views
use crate::{1bundle::{Bundle, BundleSpawner, NoBundleEffect},2change_detection::MaybeLocation,3entity::{Entity, EntitySetIterator},4world::World,5};6use core::iter::FusedIterator;78/// An iterator that spawns a series of entities and returns the [ID](Entity) of9/// each spawned entity.10///11/// If this iterator is not fully exhausted, any remaining entities will be spawned when this type is dropped.12pub struct SpawnBatchIter<'w, I>13where14I: Iterator,15I::Item: Bundle,16{17inner: I,18spawner: BundleSpawner<'w>,19caller: MaybeLocation,20}2122impl<'w, I> SpawnBatchIter<'w, I>23where24I: Iterator,25I::Item: Bundle<Effect: NoBundleEffect>,26{27#[inline]28#[track_caller]29pub(crate) fn new(world: &'w mut World, iter: I, caller: MaybeLocation) -> Self {30// Ensure all entity allocations are accounted for so `self.entities` can realloc if31// necessary32world.flush();3334let change_tick = world.change_tick();3536let (lower, upper) = iter.size_hint();37let length = upper.unwrap_or(lower);38world.entities.reserve(length as u32);3940let mut spawner = BundleSpawner::new::<I::Item>(world, change_tick);41spawner.reserve_storage(length);4243Self {44inner: iter,45spawner,46caller,47}48}49}5051impl<I> Drop for SpawnBatchIter<'_, I>52where53I: Iterator,54I::Item: Bundle,55{56fn drop(&mut self) {57// Iterate through self in order to spawn remaining bundles.58for _ in &mut *self {}59// Apply any commands from those operations.60// SAFETY: `self.spawner` will be dropped immediately after this call.61unsafe { self.spawner.flush_commands() };62}63}6465impl<I> Iterator for SpawnBatchIter<'_, I>66where67I: Iterator,68I::Item: Bundle,69{70type Item = Entity;7172fn next(&mut self) -> Option<Entity> {73let bundle = self.inner.next()?;74// SAFETY: bundle matches spawner type75unsafe { Some(self.spawner.spawn(bundle, self.caller).0) }76}7778fn size_hint(&self) -> (usize, Option<usize>) {79self.inner.size_hint()80}81}8283impl<I, T> ExactSizeIterator for SpawnBatchIter<'_, I>84where85I: ExactSizeIterator<Item = T>,86T: Bundle,87{88fn len(&self) -> usize {89self.inner.len()90}91}9293impl<I, T> FusedIterator for SpawnBatchIter<'_, I>94where95I: FusedIterator<Item = T>,96T: Bundle,97{98}99100// SAFETY: Newly spawned entities are unique.101unsafe impl<I: Iterator, T> EntitySetIterator for SpawnBatchIter<'_, I>102where103I: FusedIterator<Item = T>,104T: Bundle,105{106}107108109