use std::collections::VecDeque;
use std::path::PathBuf;
use super::{Builder, Index, TextureArray};
use crate::load::Task;
use crate::{Error, Result};
#[derive(Debug)]
pub struct Loader {
width: u16,
height: u16,
paths: Vec<PathBuf>,
}
impl Loader {
pub fn new(width: u16, height: u16) -> Loader {
Loader {
width,
height,
paths: Vec::new(),
}
}
pub fn add<P: Into<PathBuf>>(&mut self, path: P) -> Key {
self.paths.push(path.into());
Key(self.paths.len() - 1)
}
pub fn finish<F, T>(self, on_completion: F) -> Task<T>
where
F: 'static + Fn(TextureArray, Indices) -> Result<T>,
{
let total_work = self.paths.len() as u32 + 1;
Task::sequence(total_work, move |task| {
let mut builder = Builder::new(self.width, self.height);
let mut work_todo = VecDeque::from(self.paths.clone());
let mut indices = Vec::new();
while let Some(next) = work_todo.pop_front() {
let index = builder.add(next)?;
indices.push(index);
task.notify_progress(1);
}
let result =
on_completion(builder.build(task.gpu()), Indices(indices))?;
task.notify_progress(1);
Ok(result)
})
}
}
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub struct Key(usize);
#[derive(Clone, PartialEq, Debug)]
pub struct Indices(Vec<Index>);
impl Indices {
pub fn get(&self, key: Key) -> Result<Index> {
self.0
.get(key.0)
.cloned()
.ok_or(Error::TextureArray(super::Error::KeyNotFound(key.0)))
}
}