crayon 0.7.1

A small, portable and extensible game framework.
Documentation
use bincode;
use std::io::Cursor;
use std::sync::Arc;

use crate::errors::*;
use crate::res::utils::prelude::ResourceLoader;
use crate::utils::double_buf::DoubleBuf;

use super::super::backends::frame::{Command, Frame};
use super::texture::*;

pub const MAGIC: [u8; 8] = [b'V', b'T', b'E', b'X', b' ', 0, 0, 1];

#[derive(Clone)]
pub struct TextureLoader {
    frames: Arc<DoubleBuf<Frame>>,
}

impl TextureLoader {
    pub(crate) fn new(frames: Arc<DoubleBuf<Frame>>) -> Self {
        TextureLoader { frames }
    }
}

impl ResourceLoader for TextureLoader {
    type Handle = TextureHandle;
    type Intermediate = (TextureParams, Option<TextureData>);
    type Resource = TextureParams;

    fn load(&self, handle: Self::Handle, bytes: &[u8]) -> Result<Self::Intermediate> {
        if bytes[0..8] != MAGIC[..] {
            bail!("[TextureLoader] MAGIC number not match.");
        }

        let mut file = Cursor::new(&bytes[8..]);
        let params: TextureParams = bincode::deserialize_from(&mut file)?;
        let data = bincode::deserialize_from(&mut file)?;

        info!(
            "[TextureLoader] load {:?} ({}x{} - {:?}).",
            handle, params.dimensions.x, params.dimensions.y, params.format
        );

        Ok((params, Some(data)))
    }

    fn create(&self, handle: Self::Handle, item: Self::Intermediate) -> Result<Self::Resource> {
        info!("[TextureLoader] create {:?}.", handle);

        item.0.validate(item.1.as_ref())?;

        let cmd = Command::CreateTexture(Box::new((handle, item.0, item.1)));
        self.frames.write().cmds.push(cmd);

        Ok(item.0)
    }

    fn delete(&self, handle: Self::Handle, _: Self::Resource) {
        info!("[TextureLoader] delete {:?}.", handle);

        let cmd = Command::DeleteTexture(handle);
        self.frames.write().cmds.push(cmd);
    }
}