use std::error;
use std::fmt;
use std::marker::PhantomData;
use std::ops::{
Deref, DerefMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
};
use crate::backend::tess::{
IndexSlice as IndexSliceBackend, InstanceSlice as InstanceSliceBackend, Tess as TessBackend,
VertexSlice as VertexSliceBackend,
};
use crate::buffer::BufferError;
use crate::context::GraphicsContext;
use crate::vertex::{Deinterleave, Vertex, VertexDesc};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Mode {
Point,
Line,
LineStrip,
Triangle,
TriangleFan,
TriangleStrip,
Patch(usize),
}
impl fmt::Display for Mode {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
Mode::Point => f.write_str("point"),
Mode::Line => f.write_str("line"),
Mode::LineStrip => f.write_str("line strip"),
Mode::Triangle => f.write_str("triangle"),
Mode::TriangleStrip => f.write_str("triangle strip"),
Mode::TriangleFan => f.write_str("triangle fan"),
Mode::Patch(ref n) => write!(f, "patch ({})", n),
}
}
}
#[non_exhaustive]
#[derive(Debug, Eq, PartialEq)]
pub enum TessMapError {
BufferMapError(BufferError),
VertexTypeMismatch(VertexDesc, VertexDesc),
IndexTypeMismatch(TessIndexType, TessIndexType),
ForbiddenAttributelessMapping,
ForbiddenDeinterleavedMapping,
}
impl TessMapError {
pub fn buffer_map_error(e: BufferError) -> Self {
TessMapError::BufferMapError(e)
}
pub fn vertex_type_mismatch(a: VertexDesc, b: VertexDesc) -> Self {
TessMapError::VertexTypeMismatch(a, b)
}
pub fn index_type_mismatch(a: TessIndexType, b: TessIndexType) -> Self {
TessMapError::IndexTypeMismatch(a, b)
}
pub fn forbidden_attributeless_mapping() -> Self {
TessMapError::ForbiddenAttributelessMapping
}
pub fn forbidden_deinterleaved_mapping() -> Self {
TessMapError::ForbiddenDeinterleavedMapping
}
}
impl fmt::Display for TessMapError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
TessMapError::BufferMapError(ref e) => write!(f, "cannot map tessellation buffer: {}", e),
TessMapError::VertexTypeMismatch(ref a, ref b) => write!(
f,
"cannot map tessellation: vertex type mismatch between {:?} and {:?}",
a, b
),
TessMapError::IndexTypeMismatch(ref a, ref b) => write!(
f,
"cannot map tessellation: index type mismatch between {:?} and {:?}",
a, b
),
TessMapError::ForbiddenAttributelessMapping => {
f.write_str("cannot map an attributeless buffer")
}
TessMapError::ForbiddenDeinterleavedMapping => {
f.write_str("cannot map a deinterleaved buffer as interleaved")
}
}
}
}
impl From<BufferError> for TessMapError {
fn from(e: BufferError) -> Self {
TessMapError::buffer_map_error(e)
}
}
impl error::Error for TessMapError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
TessMapError::BufferMapError(e) => Some(e),
_ => None,
}
}
}
#[non_exhaustive]
#[derive(Debug, Eq, PartialEq)]
pub enum TessError {
CannotCreate(String),
AttributelessError(String),
LengthIncoherency(usize),
InternalBufferError(BufferError),
ForbiddenPrimitiveMode(Mode),
NoData,
}
impl TessError {
pub fn cannot_create(e: impl Into<String>) -> Self {
TessError::CannotCreate(e.into())
}
pub fn attributeless_error(e: impl Into<String>) -> Self {
TessError::AttributelessError(e.into())
}
pub fn length_incoherency(len: usize) -> Self {
TessError::LengthIncoherency(len)
}
pub fn internal_buffer_error(e: BufferError) -> Self {
TessError::InternalBufferError(e)
}
pub fn forbidden_primitive_mode(mode: Mode) -> Self {
TessError::ForbiddenPrimitiveMode(mode)
}
pub fn no_data() -> Self {
TessError::NoData
}
}
impl fmt::Display for TessError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
TessError::CannotCreate(ref s) => write!(f, "Creation error: {}", s),
TessError::AttributelessError(ref s) => write!(f, "Attributeless error: {}", s),
TessError::LengthIncoherency(ref s) => {
write!(f, "Incoherent size for internal buffers: {}", s)
}
TessError::InternalBufferError(ref e) => write!(f, "internal buffer error: {}", e),
TessError::ForbiddenPrimitiveMode(ref e) => write!(f, "forbidden primitive mode: {}", e),
TessError::NoData => f.write_str("no data or empty tessellation"),
}
}
}
impl From<BufferError> for TessError {
fn from(e: BufferError) -> Self {
TessError::internal_buffer_error(e)
}
}
impl error::Error for TessError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
TessError::InternalBufferError(e) => Some(e),
_ => None,
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum TessIndexType {
U8,
U16,
U32,
}
impl TessIndexType {
pub fn bytes(self) -> usize {
match self {
TessIndexType::U8 => 1,
TessIndexType::U16 => 2,
TessIndexType::U32 => 4,
}
}
}
pub unsafe trait TessIndex: Copy {
const INDEX_TYPE: Option<TessIndexType>;
fn try_into_u32(self) -> Option<u32>;
}
unsafe impl TessIndex for () {
const INDEX_TYPE: Option<TessIndexType> = None;
fn try_into_u32(self) -> Option<u32> {
None
}
}
unsafe impl TessIndex for u8 {
const INDEX_TYPE: Option<TessIndexType> = Some(TessIndexType::U8);
fn try_into_u32(self) -> Option<u32> {
Some(self.into())
}
}
unsafe impl TessIndex for u16 {
const INDEX_TYPE: Option<TessIndexType> = Some(TessIndexType::U16);
fn try_into_u32(self) -> Option<u32> {
Some(self.into())
}
}
unsafe impl TessIndex for u32 {
const INDEX_TYPE: Option<TessIndexType> = Some(TessIndexType::U32);
fn try_into_u32(self) -> Option<u32> {
Some(self.into())
}
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum Interleaved {}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum Deinterleaved {}
pub trait TessVertexData<S>: Vertex
where
S: ?Sized,
{
type Data;
fn coherent_len(data: &Self::Data) -> Result<usize, TessError>;
}
impl<V> TessVertexData<Interleaved> for V
where
V: Vertex,
{
type Data = Vec<V>;
fn coherent_len(data: &Self::Data) -> Result<usize, TessError> {
Ok(data.len())
}
}
impl<V> TessVertexData<Deinterleaved> for V
where
V: Vertex,
{
type Data = Vec<DeinterleavedData>;
fn coherent_len(data: &Self::Data) -> Result<usize, TessError> {
if data.is_empty() {
Ok(0)
} else {
let len = data[0].len;
if data[1..].iter().any(|a| a.len != len) {
Err(TessError::length_incoherency(len))
} else {
Ok(len)
}
}
}
}
#[derive(Debug, Clone)]
pub struct DeinterleavedData {
raw: Vec<u8>,
len: usize,
}
impl DeinterleavedData {
fn new() -> Self {
DeinterleavedData {
raw: Vec::new(),
len: 0,
}
}
pub fn into_vec(self) -> Vec<u8> {
self.raw
}
}
#[derive(Debug)]
pub struct TessBuilder<'a, B, V, I = (), W = (), S = Interleaved>
where
B: ?Sized,
V: TessVertexData<S>,
W: TessVertexData<S>,
S: ?Sized,
{
backend: &'a mut B,
vertex_data: Option<V::Data>,
index_data: Vec<I>,
instance_data: Option<W::Data>,
mode: Mode,
vert_nb: usize,
inst_nb: usize,
restart_index: Option<I>,
_phantom: PhantomData<&'a mut ()>,
}
impl<'a, B, V, I, W, S> TessBuilder<'a, B, V, I, W, S>
where
B: ?Sized,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
pub fn set_mode(mut self, mode: Mode) -> Self {
self.mode = mode;
self
}
pub fn set_vertex_nb(mut self, vert_nb: usize) -> Self {
self.vert_nb = vert_nb;
self
}
pub fn set_instance_nb(mut self, inst_nb: usize) -> Self {
self.inst_nb = inst_nb;
self
}
pub fn set_primitive_restart_index(mut self, restart_index: I) -> Self {
self.restart_index = Some(restart_index);
self
}
}
impl<'a, B, V, I, W, S> TessBuilder<'a, B, V, I, W, S>
where
B: ?Sized,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
pub fn new<C>(ctx: &'a mut C) -> Self
where
C: GraphicsContext<Backend = B>,
{
TessBuilder {
backend: ctx.backend(),
vertex_data: None,
index_data: Vec::new(),
instance_data: None,
mode: Mode::Point,
vert_nb: 0,
inst_nb: 0,
restart_index: None,
_phantom: PhantomData,
}
}
}
impl<'a, B, V, W, S> TessBuilder<'a, B, V, (), W, S>
where
B: ?Sized,
V: TessVertexData<S>,
W: TessVertexData<S>,
S: ?Sized,
{
pub fn set_indices<I, X>(self, indices: X) -> TessBuilder<'a, B, V, I, W, S>
where
X: Into<Vec<I>>,
{
TessBuilder {
backend: self.backend,
vertex_data: self.vertex_data,
index_data: indices.into(),
instance_data: self.instance_data,
mode: self.mode,
vert_nb: self.vert_nb,
inst_nb: self.inst_nb,
restart_index: None,
_phantom: PhantomData,
}
}
}
impl<'a, B, I, W> TessBuilder<'a, B, (), I, W, Interleaved>
where
B: ?Sized,
I: TessIndex,
W: TessVertexData<Interleaved>,
{
pub fn set_vertices<V, X>(self, vertices: X) -> TessBuilder<'a, B, V, I, W, Interleaved>
where
X: Into<Vec<V>>,
V: TessVertexData<Interleaved, Data = Vec<V>>,
{
TessBuilder {
backend: self.backend,
vertex_data: Some(vertices.into()),
index_data: self.index_data,
instance_data: self.instance_data,
mode: self.mode,
vert_nb: self.vert_nb,
inst_nb: self.inst_nb,
restart_index: self.restart_index,
_phantom: PhantomData,
}
}
}
impl<'a, B, I, V> TessBuilder<'a, B, V, I, (), Interleaved>
where
B: ?Sized,
I: TessIndex,
V: TessVertexData<Interleaved>,
{
pub fn set_instances<W, X>(self, instances: X) -> TessBuilder<'a, B, V, I, W, Interleaved>
where
X: Into<Vec<W>>,
W: TessVertexData<Interleaved, Data = Vec<W>>,
{
TessBuilder {
backend: self.backend,
vertex_data: self.vertex_data,
index_data: self.index_data,
instance_data: Some(instances.into()),
mode: self.mode,
vert_nb: self.vert_nb,
inst_nb: self.inst_nb,
restart_index: self.restart_index,
_phantom: PhantomData,
}
}
}
impl<'a, B, V, I, W> TessBuilder<'a, B, V, I, W, Deinterleaved>
where
B: ?Sized,
V: TessVertexData<Deinterleaved, Data = Vec<DeinterleavedData>>,
I: TessIndex,
W: TessVertexData<Deinterleaved, Data = Vec<DeinterleavedData>>,
{
pub fn set_attributes<A, X>(mut self, attributes: X) -> Self
where
X: Into<Vec<A>>,
V: Deinterleave<A>,
{
let build_raw = |deinterleaved: &mut Vec<DeinterleavedData>| {
let boxed_slice = attributes.into().into_boxed_slice();
let len = boxed_slice.len();
let len_bytes = len * std::mem::size_of::<A>();
let ptr = Box::into_raw(boxed_slice);
let raw = unsafe { Vec::from_raw_parts(ptr as _, len_bytes, len_bytes) };
deinterleaved[V::RANK] = DeinterleavedData { raw, len };
};
match self.vertex_data {
Some(ref mut deinterleaved) => {
build_raw(deinterleaved);
}
None => {
let mut deinterleaved = vec![DeinterleavedData::new(); V::ATTR_COUNT];
build_raw(&mut deinterleaved);
self.vertex_data = Some(deinterleaved);
}
}
self
}
pub fn set_instance_attributes<A, X>(mut self, attributes: X) -> Self
where
X: Into<Vec<A>>,
W: Deinterleave<A>,
{
let build_raw = |deinterleaved: &mut Vec<DeinterleavedData>| {
let boxed_slice = attributes.into().into_boxed_slice();
let len = boxed_slice.len();
let len_bytes = len * std::mem::size_of::<A>();
let ptr = Box::into_raw(boxed_slice);
let raw = unsafe { Vec::from_raw_parts(ptr as _, len_bytes, len_bytes) };
deinterleaved[W::RANK] = DeinterleavedData { raw, len };
};
match self.instance_data {
None => {
let mut deinterleaved = vec![DeinterleavedData::new(); W::ATTR_COUNT];
build_raw(&mut deinterleaved);
self.instance_data = Some(deinterleaved);
}
Some(ref mut deinterleaved) => {
build_raw(deinterleaved);
}
}
self
}
}
impl<'a, B, V, I, W, S> TessBuilder<'a, B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
{
pub fn build(self) -> Result<Tess<B, V, I, W, S>, TessError> {
let vert_nb = self.guess_vertex_len()?;
let inst_nb = self.guess_instance_len()?;
unsafe {
self
.backend
.build(
self.vertex_data,
self.index_data,
self.instance_data,
self.mode,
vert_nb,
inst_nb,
self.restart_index,
)
.map(|repr| Tess {
repr,
_phantom: PhantomData,
})
}
}
fn guess_vertex_len(&self) -> Result<usize, TessError> {
if self.vert_nb == 0 {
if self.index_data.is_empty() {
match self.vertex_data {
Some(ref data) => V::coherent_len(data),
None => Err(TessError::NoData),
}
} else {
Ok(self.index_data.len())
}
} else {
if self.index_data.is_empty() {
match self.vertex_data {
Some(ref data) => {
let coherent_len = V::coherent_len(data)?;
if self.vert_nb <= coherent_len {
Ok(self.vert_nb)
} else {
Err(TessError::length_incoherency(self.vert_nb))
}
}
None => Ok(self.vert_nb),
}
} else {
if self.vert_nb <= self.index_data.len() {
Ok(self.vert_nb)
} else {
Err(TessError::length_incoherency(self.vert_nb))
}
}
}
}
fn guess_instance_len(&self) -> Result<usize, TessError> {
if self.inst_nb == 0 {
match self.instance_data {
Some(ref data) => W::coherent_len(data),
None => Ok(0),
}
} else {
let coherent_len = self
.instance_data
.as_ref()
.ok_or_else(|| TessError::attributeless_error("missing number of instances"))
.and_then(W::coherent_len)?;
if self.inst_nb <= coherent_len {
Ok(self.inst_nb)
} else {
Err(TessError::length_incoherency(self.inst_nb))
}
}
}
}
#[derive(Debug)]
pub struct Tess<B, V, I = (), W = (), S = Interleaved>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
pub(crate) repr: B::TessRepr,
_phantom: PhantomData<*const S>,
}
impl<B, V, I, W, S> Tess<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
pub fn vert_nb(&self) -> usize {
unsafe { B::tess_vertices_nb(&self.repr) }
}
pub fn inst_nb(&self) -> usize {
unsafe { B::tess_instances_nb(&self.repr) }
}
pub fn indices(&mut self) -> Result<Indices<B, V, I, W, S>, TessMapError>
where
B: IndexSliceBackend<V, I, W, S>,
{
unsafe { B::indices(&mut self.repr).map(|repr| Indices { repr }) }
}
pub fn indices_mut(&mut self) -> Result<IndicesMut<B, V, I, W, S>, TessMapError>
where
B: IndexSliceBackend<V, I, W, S>,
{
unsafe { B::indices_mut(&mut self.repr).map(|repr| IndicesMut { repr }) }
}
}
impl<B, V, I, W> Tess<B, V, I, W, Interleaved>
where
B: ?Sized + TessBackend<V, I, W, Interleaved>,
V: TessVertexData<Interleaved>,
I: TessIndex,
W: TessVertexData<Interleaved>,
{
pub fn vertices(&mut self) -> Result<Vertices<B, V, I, W, Interleaved, V>, TessMapError>
where
B: VertexSliceBackend<V, I, W, Interleaved, V>,
{
unsafe { B::vertices(&mut self.repr).map(|repr| Vertices { repr }) }
}
pub fn vertices_mut(&mut self) -> Result<VerticesMut<B, V, I, W, Interleaved, V>, TessMapError>
where
B: VertexSliceBackend<V, I, W, Interleaved, V>,
{
unsafe { B::vertices_mut(&mut self.repr).map(|repr| VerticesMut { repr }) }
}
pub fn instances(&mut self) -> Result<Instances<B, V, I, W, Interleaved, V>, TessMapError>
where
B: InstanceSliceBackend<V, I, W, Interleaved, V>,
{
unsafe { B::instances(&mut self.repr).map(|repr| Instances { repr }) }
}
pub fn instances_mut(&mut self) -> Result<InstancesMut<B, V, I, W, Interleaved, V>, TessMapError>
where
B: InstanceSliceBackend<V, I, W, Interleaved, V>,
{
unsafe { B::instances_mut(&mut self.repr).map(|repr| InstancesMut { repr }) }
}
}
impl<B, V, I, W> Tess<B, V, I, W, Deinterleaved>
where
B: ?Sized + TessBackend<V, I, W, Deinterleaved>,
V: TessVertexData<Deinterleaved>,
I: TessIndex,
W: TessVertexData<Deinterleaved>,
{
pub fn vertices<T>(&mut self) -> Result<Vertices<B, V, I, W, Deinterleaved, T>, TessMapError>
where
B: VertexSliceBackend<V, I, W, Deinterleaved, T>,
V: Deinterleave<T>,
{
unsafe { B::vertices(&mut self.repr).map(|repr| Vertices { repr }) }
}
pub fn vertices_mut<T>(
&mut self,
) -> Result<VerticesMut<B, V, I, W, Deinterleaved, T>, TessMapError>
where
B: VertexSliceBackend<V, I, W, Deinterleaved, T>,
V: Deinterleave<T>,
{
unsafe { B::vertices_mut(&mut self.repr).map(|repr| VerticesMut { repr }) }
}
pub fn instances<T>(&mut self) -> Result<Instances<B, V, I, W, Deinterleaved, T>, TessMapError>
where
B: InstanceSliceBackend<V, I, W, Deinterleaved, T>,
W: Deinterleave<T>,
{
unsafe { B::instances(&mut self.repr).map(|repr| Instances { repr }) }
}
pub fn instances_mut<T>(
&mut self,
) -> Result<InstancesMut<B, V, I, W, Deinterleaved, T>, TessMapError>
where
B: InstanceSliceBackend<V, I, W, Deinterleaved, T>,
W: Deinterleave<T>,
{
unsafe { B::instances_mut(&mut self.repr).map(|repr| InstancesMut { repr }) }
}
}
#[derive(Debug)]
pub struct Vertices<B, V, I, W, S, T>
where
B: ?Sized + TessBackend<V, I, W, S> + VertexSliceBackend<V, I, W, S, T>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
repr: B::VertexSliceRepr,
}
impl<B, V, I, W, S, T> Deref for Vertices<B, V, I, W, S, T>
where
B: ?Sized + TessBackend<V, I, W, S> + VertexSliceBackend<V, I, W, S, T>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
type Target = [T];
fn deref(&self) -> &Self::Target {
self.repr.deref()
}
}
#[derive(Debug)]
pub struct VerticesMut<B, V, I, W, S, T>
where
B: ?Sized + TessBackend<V, I, W, S> + VertexSliceBackend<V, I, W, S, T>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
repr: B::VertexSliceMutRepr,
}
impl<B, V, I, W, S, T> Deref for VerticesMut<B, V, I, W, S, T>
where
B: ?Sized + TessBackend<V, I, W, S> + VertexSliceBackend<V, I, W, S, T>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
type Target = [T];
fn deref(&self) -> &Self::Target {
self.repr.deref()
}
}
impl<B, V, I, W, S, T> DerefMut for VerticesMut<B, V, I, W, S, T>
where
B: ?Sized + TessBackend<V, I, W, S> + VertexSliceBackend<V, I, W, S, T>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.repr.deref_mut()
}
}
#[derive(Debug)]
pub struct Indices<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S> + IndexSliceBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
repr: B::IndexSliceRepr,
}
impl<B, V, I, W, S> Deref for Indices<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S> + IndexSliceBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
type Target = [I];
fn deref(&self) -> &Self::Target {
self.repr.deref()
}
}
#[derive(Debug)]
pub struct IndicesMut<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S> + IndexSliceBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
repr: B::IndexSliceMutRepr,
}
impl<B, V, I, W, S> Deref for IndicesMut<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S> + IndexSliceBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
type Target = [I];
fn deref(&self) -> &Self::Target {
self.repr.deref()
}
}
impl<B, V, I, W, S> DerefMut for IndicesMut<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S> + IndexSliceBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.repr.deref_mut()
}
}
#[derive(Debug)]
pub struct Instances<B, V, I, W, S, T>
where
B: ?Sized + TessBackend<V, I, W, S> + InstanceSliceBackend<V, I, W, S, T>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
repr: B::InstanceSliceRepr,
}
impl<B, V, I, W, S, T> Deref for Instances<B, V, I, W, S, T>
where
B: ?Sized + TessBackend<V, I, W, S> + InstanceSliceBackend<V, I, W, S, T>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
type Target = [T];
fn deref(&self) -> &Self::Target {
self.repr.deref()
}
}
#[derive(Debug)]
pub struct InstancesMut<B, V, I, W, S, T>
where
B: ?Sized + TessBackend<V, I, W, S> + InstanceSliceBackend<V, I, W, S, T>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
repr: B::InstanceSliceMutRepr,
}
impl<B, V, I, W, S, T> Deref for InstancesMut<B, V, I, W, S, T>
where
B: ?Sized + TessBackend<V, I, W, S> + InstanceSliceBackend<V, I, W, S, T>,
S: ?Sized,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
{
type Target = [T];
fn deref(&self) -> &Self::Target {
self.repr.deref()
}
}
impl<B, V, I, W, S, T> DerefMut for InstancesMut<B, V, I, W, S, T>
where
B: ?Sized + TessBackend<V, I, W, S> + InstanceSliceBackend<V, I, W, S, T>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.repr.deref_mut()
}
}
#[non_exhaustive]
#[derive(Debug, Eq, PartialEq)]
pub enum TessViewError {
IncorrectViewWindow {
capacity: usize,
start: usize,
nb: usize,
},
}
impl fmt::Display for TessViewError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self {
TessViewError::IncorrectViewWindow{ capacity, start, nb } => {
write!(f, "TessView incorrect window error: requested slice size {} starting at {}, but capacity is only {}",
nb, start, capacity)
}
}
}
}
impl error::Error for TessViewError {}
#[derive(Clone)]
pub struct TessView<'a, B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
pub(crate) tess: &'a Tess<B, V, I, W, S>,
pub(crate) start_index: usize,
pub(crate) vert_nb: usize,
pub(crate) inst_nb: usize,
}
impl<'a, B, V, I, W, S> TessView<'a, B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
pub fn whole(tess: &'a Tess<B, V, I, W, S>) -> Self {
TessView {
tess,
start_index: 0,
vert_nb: tess.vert_nb(),
inst_nb: tess.inst_nb(),
}
}
pub fn inst_whole(tess: &'a Tess<B, V, I, W, S>, inst_nb: usize) -> Self {
TessView {
tess,
start_index: 0,
vert_nb: tess.vert_nb(),
inst_nb,
}
}
pub fn sub(tess: &'a Tess<B, V, I, W, S>, vert_nb: usize) -> Result<Self, TessViewError> {
let capacity = tess.vert_nb();
if vert_nb > capacity {
return Err(TessViewError::IncorrectViewWindow {
capacity,
start: 0,
nb: vert_nb,
});
}
Ok(TessView {
tess,
start_index: 0,
vert_nb,
inst_nb: tess.inst_nb(),
})
}
pub fn inst_sub(
tess: &'a Tess<B, V, I, W, S>,
vert_nb: usize,
inst_nb: usize,
) -> Result<Self, TessViewError> {
let capacity = tess.vert_nb();
if vert_nb > capacity {
return Err(TessViewError::IncorrectViewWindow {
capacity,
start: 0,
nb: vert_nb,
});
}
Ok(TessView {
tess,
start_index: 0,
vert_nb,
inst_nb,
})
}
pub fn slice(
tess: &'a Tess<B, V, I, W, S>,
start: usize,
nb: usize,
) -> Result<Self, TessViewError> {
let capacity = tess.vert_nb();
if start > capacity || nb + start > capacity {
return Err(TessViewError::IncorrectViewWindow {
capacity,
start,
nb,
});
}
Ok(TessView {
tess,
start_index: start,
vert_nb: nb,
inst_nb: tess.inst_nb(),
})
}
pub fn inst_slice(
tess: &'a Tess<B, V, I, W, S>,
start: usize,
nb: usize,
inst_nb: usize,
) -> Result<Self, TessViewError> {
let capacity = tess.vert_nb();
if start > capacity || nb + start > capacity {
return Err(TessViewError::IncorrectViewWindow {
capacity,
start,
nb,
});
}
Ok(TessView {
tess,
start_index: start,
vert_nb: nb,
inst_nb,
})
}
}
impl<'a, B, V, I, W, S> From<&'a Tess<B, V, I, W, S>> for TessView<'a, B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn from(tess: &'a Tess<B, V, I, W, S>) -> Self {
TessView::whole(tess)
}
}
pub trait View<B, V, I, W, S, Idx>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn view(&self, idx: Idx) -> Result<TessView<B, V, I, W, S>, TessViewError>;
fn inst_view(&self, idx: Idx, inst_nb: usize) -> Result<TessView<B, V, I, W, S>, TessViewError>;
}
impl<B, V, I, W, S> View<B, V, I, W, S, RangeFull> for Tess<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn view(&self, _: RangeFull) -> Result<TessView<B, V, I, W, S>, TessViewError> {
Ok(TessView::whole(self))
}
fn inst_view(
&self,
_: RangeFull,
inst_nb: usize,
) -> Result<TessView<B, V, I, W, S>, TessViewError> {
Ok(TessView::inst_whole(self, inst_nb))
}
}
impl<B, V, I, W, S> View<B, V, I, W, S, RangeTo<usize>> for Tess<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn view(&self, to: RangeTo<usize>) -> Result<TessView<B, V, I, W, S>, TessViewError> {
TessView::sub(self, to.end)
}
fn inst_view(
&self,
to: RangeTo<usize>,
inst_nb: usize,
) -> Result<TessView<B, V, I, W, S>, TessViewError> {
TessView::inst_sub(self, to.end, inst_nb)
}
}
impl<B, V, I, W, S> View<B, V, I, W, S, RangeFrom<usize>> for Tess<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn view(&self, from: RangeFrom<usize>) -> Result<TessView<B, V, I, W, S>, TessViewError> {
TessView::slice(self, from.start, self.vert_nb() - from.start)
}
fn inst_view(
&self,
from: RangeFrom<usize>,
inst_nb: usize,
) -> Result<TessView<B, V, I, W, S>, TessViewError> {
TessView::inst_slice(self, from.start, self.vert_nb() - from.start, inst_nb)
}
}
impl<B, V, I, W, S> View<B, V, I, W, S, Range<usize>> for Tess<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn view(&self, range: Range<usize>) -> Result<TessView<B, V, I, W, S>, TessViewError> {
TessView::slice(self, range.start, range.end - range.start)
}
fn inst_view(
&self,
range: Range<usize>,
inst_nb: usize,
) -> Result<TessView<B, V, I, W, S>, TessViewError> {
TessView::inst_slice(self, range.start, range.end - range.start, inst_nb)
}
}
impl<B, V, I, W, S> View<B, V, I, W, S, RangeInclusive<usize>> for Tess<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn view(&self, range: RangeInclusive<usize>) -> Result<TessView<B, V, I, W, S>, TessViewError> {
let start = *range.start();
let end = *range.end();
TessView::slice(self, start, end - start + 1)
}
fn inst_view(
&self,
range: RangeInclusive<usize>,
inst_nb: usize,
) -> Result<TessView<B, V, I, W, S>, TessViewError> {
let start = *range.start();
let end = *range.end();
TessView::inst_slice(self, start, end - start + 1, inst_nb)
}
}
impl<B, V, I, W, S> View<B, V, I, W, S, RangeToInclusive<usize>> for Tess<B, V, I, W, S>
where
B: ?Sized + TessBackend<V, I, W, S>,
V: TessVertexData<S>,
I: TessIndex,
W: TessVertexData<S>,
S: ?Sized,
{
fn view(&self, to: RangeToInclusive<usize>) -> Result<TessView<B, V, I, W, S>, TessViewError> {
TessView::sub(self, to.end + 1)
}
fn inst_view(
&self,
to: RangeToInclusive<usize>,
inst_nb: usize,
) -> Result<TessView<B, V, I, W, S>, TessViewError> {
TessView::inst_sub(self, to.end + 1, inst_nb)
}
}