use std::error;
use std::fmt;
use std::sync::Arc;
use SafeDeref;
use buffer::BufferAccess;
use format::Format;
use pipeline::vertex::VertexMemberTy;
use vk;
pub unsafe trait VertexDefinition<I>
: VertexSource<Vec<Arc<BufferAccess + Send + Sync>>> {
type BuffersIter: ExactSizeIterator<Item = (u32, usize, InputRate)>;
type AttribsIter: ExactSizeIterator<Item = (u32, u32, AttributeInfo)>;
fn definition(
&self, interface: &I)
-> Result<(Self::BuffersIter, Self::AttribsIter), IncompatibleVertexDefinitionError>;
}
unsafe impl<I, T> VertexDefinition<I> for T
where T: SafeDeref,
T::Target: VertexDefinition<I>
{
type BuffersIter = <T::Target as VertexDefinition<I>>::BuffersIter;
type AttribsIter = <T::Target as VertexDefinition<I>>::AttribsIter;
#[inline]
fn definition(
&self, interface: &I)
-> Result<(Self::BuffersIter, Self::AttribsIter), IncompatibleVertexDefinitionError> {
(**self).definition(interface)
}
}
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum InputRate {
Vertex = vk::VERTEX_INPUT_RATE_VERTEX,
Instance = vk::VERTEX_INPUT_RATE_INSTANCE,
}
pub struct AttributeInfo {
pub offset: usize,
pub format: Format,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum IncompatibleVertexDefinitionError {
MissingAttribute {
attribute: String,
},
FormatMismatch {
attribute: String,
shader: (Format, usize),
definition: (VertexMemberTy, usize),
},
}
impl error::Error for IncompatibleVertexDefinitionError {
#[inline]
fn description(&self) -> &str {
match *self {
IncompatibleVertexDefinitionError::MissingAttribute { .. } => "an attribute is missing",
IncompatibleVertexDefinitionError::FormatMismatch { .. } => {
"the format of an attribute does not match"
},
}
}
}
impl fmt::Display for IncompatibleVertexDefinitionError {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(fmt, "{}", error::Error::description(self))
}
}
pub unsafe trait VertexSource<L> {
fn decode(&self, L) -> (Vec<Box<BufferAccess + Send + Sync>>, usize, usize);
}
unsafe impl<L, T> VertexSource<L> for T
where T: SafeDeref,
T::Target: VertexSource<L>
{
#[inline]
fn decode(&self, list: L) -> (Vec<Box<BufferAccess + Send + Sync>>, usize, usize) {
(**self).decode(list)
}
}