use std::iter;
use buffer::BufferAccess;
use descriptor::descriptor::DescriptorDesc;
use descriptor::descriptor_set::DescriptorSet;
use descriptor::descriptor_set::DescriptorSetDesc;
use descriptor::descriptor_set::UnsafeDescriptorSet;
use image::ImageAccess;
pub unsafe trait DescriptorSetsCollection {
fn num_sets(&self) -> usize;
fn descriptor_set(&self, set: usize) -> Option<&UnsafeDescriptorSet>;
fn num_bindings_in_set(&self, set: usize) -> Option<usize>;
fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc>;
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a>;
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a>;
}
unsafe impl DescriptorSetsCollection for () {
#[inline]
fn num_sets(&self) -> usize {
0
}
#[inline]
fn descriptor_set(&self, set: usize) -> Option<&UnsafeDescriptorSet> {
None
}
#[inline]
fn num_bindings_in_set(&self, set: usize) -> Option<usize> {
None
}
#[inline]
fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
None
}
#[inline]
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a> {
Box::new(iter::empty())
}
#[inline]
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a> {
Box::new(iter::empty())
}
}
unsafe impl<T> DescriptorSetsCollection for T
where T: DescriptorSet
{
#[inline]
fn num_sets(&self) -> usize {
1
}
#[inline]
fn descriptor_set(&self, set: usize) -> Option<&UnsafeDescriptorSet> {
match set {
0 => Some(self.inner()),
_ => None
}
}
#[inline]
fn num_bindings_in_set(&self, set: usize) -> Option<usize> {
match set {
0 => Some(self.num_bindings()),
_ => None
}
}
#[inline]
fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
match set {
0 => self.descriptor(binding),
_ => None
}
}
#[inline]
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a> {
DescriptorSet::buffers_list(self)
}
#[inline]
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a> {
DescriptorSet::images_list(self)
}
}
macro_rules! impl_collection {
($first:ident $(, $others:ident)*) => (
unsafe impl<$first$(, $others)*> DescriptorSetsCollection for ($first, $($others),*)
where $first: DescriptorSet + DescriptorSetDesc
$(, $others: DescriptorSet + DescriptorSetDesc)*
{
#[inline]
fn num_sets(&self) -> usize {
#![allow(non_snake_case)]
1 $( + {let $others=0;1})*
}
#[inline]
fn descriptor_set(&self, mut set: usize) -> Option<&UnsafeDescriptorSet> {
#![allow(non_snake_case)]
#![allow(unused_mut)]
if set == 0 {
return Some(self.0.inner());
}
let &(_, $(ref $others,)*) = self;
$(
set -= 1;
if set == 0 {
return Some($others.inner());
}
)*
None
}
#[inline]
fn num_bindings_in_set(&self, mut set: usize) -> Option<usize> {
#![allow(non_snake_case)]
#![allow(unused_mut)]
if set == 0 {
return Some(self.0.num_bindings());
}
let &(_, $(ref $others,)*) = self;
$(
set -= 1;
if set == 0 {
return Some($others.num_bindings());
}
)*
None
}
#[inline]
fn descriptor(&self, mut set: usize, binding: usize) -> Option<DescriptorDesc> {
#![allow(non_snake_case)]
#![allow(unused_mut)]
if set == 0 {
return self.0.descriptor(binding);
}
let &(_, $(ref $others,)*) = self;
$(
set -= 1;
if set == 0 {
return $others.descriptor(binding);
}
)*
None
}
#[inline]
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a> {
#![allow(non_snake_case)]
let &(ref first, $(ref $others,)*) = self;
let mut output = Vec::new();
output.extend(first.buffers_list());
$(
output.extend($others.buffers_list());
)*
Box::new(output.into_iter())
}
#[inline]
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a> {
#![allow(non_snake_case)]
let &(ref first, $(ref $others,)*) = self;
let mut output = Vec::new();
output.extend(first.images_list());
$(
output.extend($others.images_list());
)*
Box::new(output.into_iter())
}
}
impl_collection!($($others),*);
);
() => ();
}
impl_collection!(Z, Y, X, W, V, U, T, S, R, Q, P, O, N, M, L, K, J, I, H, G, F, E, D, C, B, A);