game_kernel_utils 0.1.0

Miscellaneous utilities for game_kernel
Documentation
#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}

pub mod hierarchy;

use std::collections::HashMap;
#[derive(Clone)]
pub struct AutoIndexMap<T> {
    data: Vec<T>,
    current_index: u64,
}

pub type KeyType = u64;
impl<T> AutoIndexMap<T> {
    pub fn new() -> Self {
        Self {
            data: Vec::new(),
            current_index: 0,
        }
    }

    pub fn insert(&mut self, v: T) -> u64 {
        self.data.push(v);
        self.data.len() as u64 - 1
    }

    pub fn iter(&self) -> std::iter::Enumerate<std::slice::Iter<'_, T>> {
        self.data
            .iter()
            .enumerate()
    }

    pub fn get(&self, k: KeyType) -> Option<&T> {
        self.data.get(k as usize)
    }

    pub fn get_mut(&mut self, k: KeyType) -> Option<&mut T> {
        self.data.get_mut(k as usize)
    }

    pub fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    pub fn len(&self) -> usize {
        self.data.len()
    }
}

impl<T: Eq + PartialEq> AutoIndexMap<T> {
    pub fn contains(&self, x: &T) -> bool {
        self.data.contains(x)
    }
}

use std::ops::Index;

impl<T> Index<&KeyType> for AutoIndexMap<T> {
    type Output = T;

    fn index(&self, index: &KeyType) -> &T {
        &self.data[*index as usize]
    }
}

pub trait MapAbstract<K, V> {
    fn get<Q: Sized>(&self, k: &Q) -> Option<&V>
    where
        Self: Sized;

    fn get_mut<Q: Sized>(&mut self, k: &Q) -> Option<&mut V>
    where
        Self: Sized;
}

impl<K, V> MapAbstract<K, V> for HashMap<K, V> {
    fn get<Q: Sized>(&self, k: &Q) -> Option<&V>
    where
        Self: Sized,
    {
        self.get(k)
    }

    fn get_mut<Q: Sized>(&mut self, k: &Q) -> Option<&mut V>
    where
        Self: Sized,
    {
        self.get_mut(k)
    }
}

use std::marker::PhantomData;

pub struct MappedMap<K, V, N, M, F, FM>
where
    M: MapAbstract<K, V>,
    F: Fn(&V) -> &N,
    FM: Fn(&mut V) -> &mut N,
{
    mapped: M,
    f: F,
    fm: FM,
    p1: PhantomData<K>,
    p2: PhantomData<V>,
    p3: PhantomData<N>,
}

impl<K, V, N, M, F, FM> MappedMap<K, V, N, M, F, FM>
where
    M: MapAbstract<K, V>,
    F: Fn(&V) -> &N,
    FM: Fn(&mut V) -> &mut N,
{
    fn new(mapped: M, f: F, fm: FM) -> Self {
        Self {
            mapped,
            f,
            fm,
            p1: PhantomData,
            p2: PhantomData,
            p3: PhantomData,
        }
    }

    fn get<Q: Sized>(&self, k: &Q) -> Option<&N> {
        Some((self.f)(self.mapped.get(k)?)) //doh
    }

    fn get_mut<Q: Sized>(&mut self, k: &Q) -> Option<&mut N> {
        Some((self.fm)(self.mapped.get_mut(k)?)) //doh
    }
}

impl<K, V, N, M, F, FM> MapAbstract<K, N> for MappedMap<K, V, N, M, F, FM>
where
    M: MapAbstract<K, V>,
    F: Fn(&V) -> &N,
    FM: Fn(&mut V) -> &mut N,
{
    fn get<Q: Sized>(&self, k: &Q) -> Option<&N>
    where
        Self: Sized,
    {
        self.get(k)
    }

    fn get_mut<Q: Sized>(&mut self, k: &Q) -> Option<&mut N>
    where
        Self: Sized,
    {
        self.get_mut(k)
    }
}

pub trait MapMap<K, V> {
    fn map_map<N, F, FM, M>(self, f: F, fm: FM) -> MappedMap<K, V, N, Self, F, FM>
    where
        F: Fn(&V) -> &N,
        FM: Fn(&mut V) -> &mut N,
        Self: MapAbstract<K, V>,
        Self: Sized,
    {
        MappedMap::new(self, f, fm)
    }
}

impl<K, V> MapMap<K, V> for HashMap<K, V> {}

extern crate cgmath;
use cgmath::{Matrix3, Matrix4, /*BaseFloat, InnerSpace, SquareMatrix*/};

/*pub trait MatOps<T> {
    fn transponse(&self) -> Matrix3<T>;
    fn inverse(&self) -> Matrix3<T>;
}

fn mat3_transponse<T: Copy>(a: &Matrix3<T>) -> Matrix3<T> {
    Matrix3::new(a[0][0], a[1][0], a[2][0],
                 a[0][1], a[1][1], a[2][1],
                 a[0][2], a[1][2], a[2][2],)
}

*/
pub fn mat4_transponse<T: Copy>(a: &Matrix4<T>) -> Matrix4<T> {
    Matrix4::new(a[0][0], a[1][0], a[2][0], a[3][0],
                 a[0][1], a[1][1], a[2][1], a[3][1],
                 a[0][2], a[1][2], a[2][2], a[3][2],
                 a[0][3], a[1][3], a[2][3], a[3][3],)
}
/*
impl<T: BaseFloat> MatOps<T> for Matrix3<T> {
    fn transponse(&self) -> Matrix3<T> {
        mat3_transponse(self)
    }

    fn inverse(&self) -> Matrix3<T> {
        let mt = Matrix3::new(self[0][0], self[1][0], self[2][0],
                     self[0][1], self[1][1], self[2][1],
                     self[0][2], self[1][2], self[2][2],);
        let det = mt.x.cross(mt.y).dot(mt.z);
        let adj = Matrix3::from_cols(mt.y.cross(mt.z), mt.z.cross(mt.x), mt.x.cross(mt.y));
        adj/det
    }
}*/

pub fn submat3<T: Copy>(a: Matrix4<T>) -> Matrix3<T> {
    Matrix3::new(a[0][0], a[0][1], a[0][2], 
                 a[1][0], a[1][1], a[1][2],
                 a[2][0], a[2][1], a[2][2],)
}

pub fn mat3_extend(a: Matrix3<f32>) -> [[f32; 4]; 3] {
    [[a[0][0], a[0][1], a[0][2], 0.0],
    [a[1][0], a[1][1], a[1][2], 0.0],
    [a[2][0], a[2][1], a[2][2], 0.0],]
}