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};
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 {}
}