dunge 0.3.11

Typesafe and portable 3d render library
Documentation
//! Shader group types and traits.

use {
    crate::{
        StorageValue,
        buffer::Sampler,
        sl::{Define, Global, GlobalOut, Ret},
        storage::{Storage, Uniform},
        types::{self, MemberData, MemberType, Space},
        value::UniformValue,
    },
    dunge_shade::group::Group,
};

pub use dunge_shade::group::{Projection, Take};

/// Describes a group member type projection.
///
/// The trait is sealed because the derive macro relies on no new types being used.
pub trait MemberProjection: s::Sealed {
    const MEMBER: MemberData;
    type Field;
    fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field;
}

impl<M> s::Sealed for &M where M: s::Sealed {}

impl<M> MemberProjection for &M
where
    M: MemberProjection,
{
    const MEMBER: MemberData = M::MEMBER;
    type Field = M::Field;

    fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field {
        M::member_projection(id, binding, out)
    }
}

impl<V> s::Sealed for Uniform<V> where V: UniformValue<Type: types::Member> {}

impl<V> MemberProjection for Uniform<V>
where
    V: UniformValue<Type: types::Member>,
{
    const MEMBER: MemberData = MemberData {
        ty: <V::Type as types::Member>::MEMBER_TYPE,
        space: Space::Uniform,
    };

    type Field = Ret<Global, V::GlobalType>;

    fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field {
        Global::new(id, binding, out)
    }
}

impl<V> Group for Uniform<V>
where
    Self: MemberProjection<Field: Projection>,
{
    type Projection = <Self as MemberProjection>::Field;
    const DEF: Define<MemberData> = Define::new(&[Self::MEMBER]);
}

impl<V, M> s::Sealed for Storage<V, M>
where
    V: StorageValue + ?Sized,
    M: types::Mutability,
{
}

impl<V, M> MemberProjection for Storage<V, M>
where
    V: StorageValue<Type: types::Member> + ?Sized,
    M: types::Mutability,
{
    const MEMBER: MemberData = MemberData {
        ty: <V::Type as types::Member>::MEMBER_TYPE,
        space: Space::Storage {
            mutable: M::MUTABLE,
        },
    };

    type Field = Ret<Global<M>, V::GlobalType>;

    fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field {
        Global::new(id, binding, out)
    }
}

impl<V, M> Group for Storage<V, M>
where
    V: ?Sized,
    Self: MemberProjection<Field: Projection>,
{
    type Projection = <Self as MemberProjection>::Field;
    const DEF: Define<MemberData> = Define::new(&[Self::MEMBER]);
}

#[derive(Clone)]
pub struct BoundTexture(pub(crate) wgpu::TextureView);

impl s::Sealed for BoundTexture {}

impl MemberProjection for BoundTexture {
    const MEMBER: MemberData = MemberData {
        ty: MemberType::Tx2df,
        space: Space::Handle,
    };

    type Field = Ret<Global, types::Texture2d<f32>>;

    fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field {
        Global::new(id, binding, out)
    }
}

impl Group for BoundTexture {
    type Projection = <Self as MemberProjection>::Field;
    const DEF: Define<MemberData> = Define::new(&[Self::MEMBER]);
}

impl s::Sealed for Sampler {}

impl MemberProjection for Sampler {
    const MEMBER: MemberData = MemberData {
        ty: MemberType::Sampl,
        space: Space::Handle,
    };

    type Field = Ret<Global, types::Sampler>;

    fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field {
        Global::new(id, binding, out)
    }
}

impl Group for Sampler {
    type Projection = <Self as MemberProjection>::Field;
    const DEF: Define<MemberData> = Define::new(&[Self::MEMBER]);
}

mod s {
    pub trait Sealed {}
}