rustbatch 0.4.0

purely game dewelopment crate that offers simple but powerfull 2D rendering and some fast solutions for game world bottle necks
Documentation
/// ComponentArray is alternative to storing components in hashmap. Its considerable faster to
/// access elements of course there is a cost for that. You cannot choose your own ids ComponentArray
/// generates them for you. Model is surprisingly simple but powerful. To use this properly you have
/// to ALWAYS remove no longer needed component unless you like memory leaks.
pub struct ComponentArray<T> {
    inner: Vec<Option<T>>,
    ids: Vec<usize>,
    len: usize,
    id: usize,
}

impl<T> ComponentArray<T> {
    #[inline]
    pub fn new() -> Self {
        Self {
            inner: vec![None],
            ids: vec![],
            len: 0,
            id: 0,
        }
    }

    /// insert takes an value and returns id to is. (Its not really id but you can use it like it)
    #[inline]
    pub fn insert(&mut self, component: T) -> usize {
        self.len = self.inner.len();
        if self.ids.is_empty() {
            self.inner.push(Some(component));
            return self.len
        }
        self.len = self.ids.len() - 1;
        self.id = self.ids[self.len];
        self.inner[self.id] = Some(component);
        self.ids.truncate(self.len);

        self.id
    }

    #[inline]
    pub fn len(&self) -> usize {
        self.inner.len()
    }

    /// remove is important. Always remove the objects so memory can be reused for another one.
    #[inline]
    pub fn remove(&mut self, id: usize) -> T {
        if let None = self.inner[id] {
            panic!("value with given id is already none, call put_back and then remove, calling \
            just get instead of remove produces memory leak because space is still considered occupied.");
        }
        self.ids.push(id);
        unsafe { self.get(id).unwrap() }
    }

    #[inline]
    pub fn remove_if_present(&mut self, id: usize) -> Option<T> {
        if let None = self.inner[id] {
            return None
        }
        self.ids.push(id);
        unsafe { self.get(id) }
    }

    /// get is not equivalent fo remove, if you do not put back what you taken you are leaking memory
    /// because ComponentArray still considers it occupied. Function is here to solve situations when
    /// you need mutable and immutable asses to array elements at the same time
    #[inline]
    pub unsafe fn get(&mut self, id: usize) -> Option<T> {
        std::mem::replace(&mut self.inner[id], None)
    }

    /// Call this after get on the same id. This function is unsafe for a reason, you can very easily
    /// put your data somewhere where its considered free and it can then be overwrite by insert call
    #[inline]
    pub unsafe fn put_back(&mut self, id: usize, component: T) {
        self.inner[id] = Some(component);
    }

    /// get_ref returns reference to element or none
    #[inline]
    pub fn get_ref(&self, id: usize) -> &Option<T> {
        &self.inner[id]
    }

    /// get:mut returns mutable reference or none
    #[inline]
    pub fn get_mut(&mut self, id: usize) -> &mut Option<T> {
        &mut self.inner[id]
    }
}