use rayon::prelude::*;
use crate::graphics::gpu;
use crate::graphics::{Image, IntoQuad, Target};
pub struct Batch {
image: Image,
instances: Vec<gpu::Quad>,
x_unit: f32,
y_unit: f32,
}
impl Batch {
pub fn new(image: Image) -> Self {
let x_unit = 1.0 / image.width() as f32;
let y_unit = 1.0 / image.height() as f32;
Self {
image,
instances: Vec::new(),
x_unit,
y_unit,
}
}
#[inline]
pub fn add<Q: IntoQuad>(&mut self, quad: Q) {
let instance =
gpu::Quad::from(quad.into_quad(self.x_unit, self.y_unit));
self.instances.push(instance);
}
pub fn draw(&self, target: &mut Target<'_>) {
target.draw_texture_quads(&self.image.texture, &self.instances[..]);
}
pub fn clear(&mut self) {
self.instances.clear();
}
}
impl std::fmt::Debug for Batch {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Batch {{ image: {:?} }}", self.image,)
}
}
impl<Q: IntoQuad> Extend<Q> for Batch {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = Q>,
{
let iter = iter.into_iter();
let x_unit = self.x_unit;
let y_unit = self.y_unit;
self.instances.extend(
iter.map(|quad| gpu::Quad::from(quad.into_quad(x_unit, y_unit))),
);
}
}
impl<Q: IntoQuad + Send> ParallelExtend<Q> for Batch {
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = Q>,
{
let par_iter = par_iter.into_par_iter();
let x_unit = self.x_unit;
let y_unit = self.y_unit;
self.instances.par_extend(
par_iter
.map(|quad| gpu::Quad::from(quad.into_quad(x_unit, y_unit))),
);
}
}