use std::marker::PhantomData;
use gfx_core::{ResourceViewSlot, UnorderedViewSlot, SamplerSlot, Resources};
use gfx_core::{handle, shade};
use gfx_core::factory::Phantom;
use gfx_core::format::Format;
use super::{DataLink, DataBind, RawDataSet};
pub struct ShaderResource<T>(Option<ResourceViewSlot>, PhantomData<T>);
pub struct UnorderedAccess<T>(Option<UnorderedViewSlot>, PhantomData<T>);
pub struct Sampler(Option<SamplerSlot>);
pub struct TextureSampler<T>(ShaderResource<T>, Sampler);
impl<'a, T> DataLink<'a> for ShaderResource<T> {
type Init = &'a str;
fn new() -> Self {
ShaderResource(None, PhantomData)
}
fn is_active(&self) -> bool {
self.0.is_some()
}
fn link_resource_view(&mut self, var: &shade::TextureVar, init: &Self::Init)
-> Option<Result<(), Format>> {
if *init == var.name {
self.0 = Some(var.slot);
Some(Ok(())) }else {
None
}
}
}
impl<R: Resources, T> DataBind<R> for ShaderResource<T> {
type Data = handle::ShaderResourceView<R, T>;
fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
if let Some(slot) = self.0 {
let value = Some(man.ref_srv(data.raw()).clone());
out.resource_views.0[slot as usize] = value;
}
}
}
impl<'a, T> DataLink<'a> for UnorderedAccess<T> {
type Init = &'a str;
fn new() -> Self {
UnorderedAccess(None, PhantomData)
}
fn is_active(&self) -> bool {
self.0.is_some()
}
fn link_unordered_view(&mut self, var: &shade::UnorderedVar, init: &Self::Init)
-> Option<Result<(), Format>> {
if *init == var.name {
self.0 = Some(var.slot);
Some(Ok(())) }else {
None
}
}
}
impl<R: Resources, T> DataBind<R> for UnorderedAccess<T> {
type Data = handle::UnorderedAccessView<R, T>;
fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
if let Some(slot) = self.0 {
let value = Some(man.ref_uav(data.raw()).clone());
out.unordered_views.0[slot as usize] = value;
}
}
}
impl<'a> DataLink<'a> for Sampler {
type Init = &'a str;
fn new() -> Self {
Sampler(None)
}
fn is_active(&self) -> bool {
self.0.is_some()
}
fn link_sampler(&mut self, var: &shade::SamplerVar, init: &Self::Init) -> Option<()> {
if *init == var.name {
self.0 = Some(var.slot);
Some(())
}else {
None
}
}
}
impl<R: Resources> DataBind<R> for Sampler {
type Data = handle::Sampler<R>;
fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
if let Some(slot) = self.0 {
let value = Some(man.ref_sampler(data).clone());
out.samplers.0[slot as usize] = value;
}
}
}
impl<'a, T> DataLink<'a> for TextureSampler<T> {
type Init = &'a str;
fn new() -> Self {
TextureSampler(ShaderResource::new(), Sampler::new())
}
fn is_active(&self) -> bool {
self.0.is_active()
}
fn link_resource_view(&mut self, var: &shade::TextureVar, init: &Self::Init)
-> Option<Result<(), Format>> {
self.0.link_resource_view(var, init)
}
fn link_sampler(&mut self, var: &shade::SamplerVar, init: &Self::Init) -> Option<()> {
self.1.link_sampler(var, init)
}
}
impl<R: Resources, T> DataBind<R> for TextureSampler<T> {
type Data = (handle::ShaderResourceView<R, T>, handle::Sampler<R>);
fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
self.0.bind_to(out, &data.0, man);
self.1.bind_to(out, &data.1, man);
}
}