matrix_engine 0.2.4

a small game engine developed by drmatrix
Documentation
use std::marker::PhantomData;

use wgpu::{BindGroup, BindGroupLayout, BindGroupLayoutDescriptor};

use crate::{impl_all, renderer::pipelines::device_queue::DeviceQueue};

use super::bind::MatrixBindable;

pub struct MatrixBindGroupLayout<G: MatrixBindGroupable> {
    layout: BindGroupLayout,
    marker: PhantomData<G>,
}

impl<G: MatrixBindGroupable> MatrixBindGroupLayout<G> {
    pub fn new(device_queue: &DeviceQueue) -> Self {
        Self {
            layout: G::create_group_layout(device_queue),
            marker: PhantomData,
        }
    }
    pub fn create_group(&self, device_queue: &DeviceQueue, data: &G) -> MatrixBindGroup<G> {
        MatrixBindGroup::new(data.create_group(device_queue, self))
    }

    pub fn layout(&self) -> &BindGroupLayout {
        &self.layout
    }
}

pub trait MatrixBindGroupable {
    fn layout_name() -> &'static str {
        "matrix bind group default name"
    }
    fn group_name() -> &'static str {
        "matrix group default name"
    }

    fn create_group_layout(device_queue: &DeviceQueue) -> BindGroupLayout;

    fn create_group(
        &self,
        device_queue: &DeviceQueue,
        layout: &MatrixBindGroupLayout<Self>,
    ) -> BindGroup
    where
        Self: Sized;
}

macro_rules! impl_group {
    ($($t:tt)*) => {
        impl<$($t:MatrixBindable,)*> MatrixBindGroupable for ($($t,)*) {
            #[allow(non_snake_case)]
            fn create_group_layout(device_queue:&DeviceQueue) -> BindGroupLayout {
                let mut i = 0;
                $(let $t =$t::bind_layout_entry({i+=1;i-1});)*
                device_queue
                    .device()
                    .create_bind_group_layout(&BindGroupLayoutDescriptor {
                        label: Some(Self::layout_name()),
                        entries: &[$($t,)*],
                    })
            }

            #[allow(non_snake_case)]
            fn create_group(&self,device_queue:&DeviceQueue, layout: &MatrixBindGroupLayout<Self>) -> BindGroup where Self:Sized {
                let ($($t,)*) = self;
                let mut i = 0;
                $(let $t =$t.bind_entry({i+=1;i-1});)*
                device_queue
                    .device()
                    .create_bind_group(&wgpu::BindGroupDescriptor {
                        label: Some(&Self::group_name()),
                        layout: layout.layout(),
                        entries: &[$($t,)*],
                    })
            }
        }
    };
}

impl_all!(impl_group);

pub struct MatrixBindGroup<G: MatrixBindGroupable> {
    group: BindGroup,
    marker: PhantomData<G>,
}

impl<G: MatrixBindGroupable> MatrixBindGroup<G> {
    pub fn new(group: BindGroup) -> Self {
        Self {
            group,
            marker: PhantomData,
        }
    }

    pub fn group(&self) -> &BindGroup {
        &self.group
    }
}