use std::iter::FusedIterator;
use std::mem::transmute;
use crate::archetype::{Archetype, ArchetypeWorldIndex, ComponentInfo, ShareArchetype};
use crate::insert::{Insert, InsertComponents};
use crate::world::{Entity, World};
pub struct InsertBatchIter<'w, I, Ins>
where
I: Iterator<Item = <Ins as InsertComponents>::Item>,
Ins: InsertComponents,
{
world: &'w mut World,
inner: I,
state: (
ArchetypeWorldIndex,
ShareArchetype,
<Ins as InsertComponents>::State,
),
}
impl<'w, I, Ins> InsertBatchIter<'w, I, Ins>
where
I: Iterator<Item = <Ins as InsertComponents>::Item>,
Ins: InsertComponents,
{
#[inline]
pub(crate) fn new(world: &'w mut World, iter: I) -> Self {
let (lower, upper) = iter.size_hint();
let length = upper.unwrap_or(lower);
let components = Ins::components();
let id = ComponentInfo::calc_id(&components);
let (ar_index, ar) = world.find_archtype(id, components);
let s = Ins::init_state(world, &ar);
let ptr = ShareArchetype::as_ptr(&ar);
let ar_mut: &mut Archetype = unsafe { transmute(ptr) };
ar_mut.table.reserve(length);
Self {
world,
inner: iter,
state: (ar_index, ar, s),
}
}
}
impl<I, Ins> Drop for InsertBatchIter<'_, I, Ins>
where
I: Iterator<Item = <Ins as InsertComponents>::Item>,
Ins: InsertComponents,
{
fn drop(&mut self) {
for _ in self {}
}
}
impl<I, Ins> Iterator for InsertBatchIter<'_, I, Ins>
where
I: Iterator<Item = <Ins as InsertComponents>::Item>,
Ins: InsertComponents,
{
type Item = Entity;
fn next(&mut self) -> Option<Entity> {
let item = self.inner.next()?;
let i = Insert::<Ins>::new(&self.world, &mut self.state);
Some(i.insert(item))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<I, Ins> ExactSizeIterator for InsertBatchIter<'_, I, Ins>
where
I: ExactSizeIterator<Item = <Ins as InsertComponents>::Item>,
Ins: InsertComponents,
{
fn len(&self) -> usize {
self.inner.len()
}
}
impl<I, Ins> FusedIterator for InsertBatchIter<'_, I, Ins>
where
I: FusedIterator<Item = <Ins as InsertComponents>::Item>,
Ins: InsertComponents,
{
}