use gl::types::*;
use std::mem;
use std::marker::PhantomData;
use std::ops;
use std::borrow::{Borrow, BorrowMut};
use super::traits::*;
#[cfg(not(feature="webgl"))]
use ::Result;
#[cfg(not(feature="webgl"))]
use super::map::*;
#[derive(Debug, Eq, PartialEq)]
pub struct Range<T, B, BB>{
pub(super) buffer: BB,
pub(super) range: ops::Range<usize>,
pub(super) marker_type: PhantomData<T>,
pub(super) marker_buffer: PhantomData<B>,
}
impl<T, B, BB: Clone> Clone for Range<T,B,BB>{
fn clone(&self) -> Range<T,B,BB>{
Range{
buffer: self.buffer.clone(),
range: self.range.clone(),
marker_type: PhantomData,
marker_buffer: PhantomData,
}
}
}
impl<T: 'static, B, BB: Borrow<B>> Range<T,B, BB>{
pub fn is_empty(&self) -> bool {
self.range.start == self.range.end
}
pub fn len(&self) -> usize{
self.range.end - self.range.start
}
pub fn bytes(&self) -> usize{
self.len() * mem::size_of::<T>()
}
pub fn capacity(&self) -> usize{
self.len()
}
pub fn capacity_bytes(&self) -> usize{
self.len() * mem::size_of::<T>()
}
pub fn stride(&self) -> usize{
mem::size_of::<T>()
}
pub fn start(&self) -> usize{
self.range.start
}
pub fn end(&self) -> usize{
self.range.end
}
}
impl<T: 'static, B: TypedBuffer<T>, BB: Borrow<B>> Range<T,B, BB> {
pub fn join(self, other: Range<T,B,BB>) -> ::std::result::Result<Self, (Self, Self)>{
if self.buffer.borrow().id() == other.buffer.borrow().id(){
if self.end() == other.start() {
Ok(Range{
buffer: self.buffer,
range: self.range.start .. other.range.end,
marker_type: PhantomData,
marker_buffer: PhantomData
})
}else if self.start() == other.end() {
Ok(Range{
buffer: self.buffer,
range: other.range.start .. self.range.end,
marker_type: PhantomData,
marker_buffer: PhantomData
})
}else{
Err((self, other))
}
}else{
Err((self, other))
}
}
}
impl<T: 'static, B, BB: Borrow<B> + Clone> Range<T,B, BB>{
pub fn split(self, offset: usize) -> (Range<T,B,BB>, Range<T,B,BB>){
let r1 = Range{
buffer: self.buffer.clone(),
range: self.range.start .. self.range.start + offset,
marker_type: PhantomData,
marker_buffer: PhantomData,
};
let r2 = Range{
buffer: self.buffer,
range: self.range.start + offset .. self.range.end,
marker_type: PhantomData,
marker_buffer: PhantomData,
};
(r1, r2)
}
}
impl<T: 'static, B: TypedBuffer<T>, BB: Borrow<B>> Range<T,B,BB>{
pub fn id(&self) -> GLuint{
self.buffer.borrow().id()
}
}
impl<T, B: Cast<T> + TypedBuffer<u8>> Cast<T> for Range<u8,B,B>{
type CastTo = Range<T, <B as Cast<T>>::CastTo, <B as Cast<T>>::CastTo>;
fn cast(self) -> Self::CastTo{
let start = self.range.start / mem::size_of::<T>();
let end = self.range.end / mem::size_of::<T>();
Range{
buffer: self.buffer.cast(),
range: start .. end,
marker_type: PhantomData,
marker_buffer: PhantomData,
}
}
}
#[cfg(not(feature="webgl"))]
impl<T: 'static, B: WithMapRange<T>, BB: Borrow<B>> Range<T,B,BB>{
pub fn with_map_read<F: FnMut(&[T])>(&self, flags: MapReadFlags, f: F) -> Result<()>{
self.buffer
.borrow()
.with_map_range_read(self.range.start, self.range.end - self.range.start, flags, f)
}
}
#[cfg(not(feature="webgl"))]
impl<T: 'static, B: MapRange<T>, BB: BorrowMut<B>> Range<T,B,BB>{
pub fn map_read(&mut self, flags: MapReadFlags) -> Result<MapRead<T, B>>{
self.buffer
.borrow_mut()
.map_range_read(self.range.start, self.range.end - self.range.start, flags)
}
}
#[cfg(not(feature="webgl"))]
impl<T: 'static, B: MapRangeMut<T>, BB: BorrowMut<B>> Range<T,B,BB>{
pub fn map_write(&mut self, flags: MapWriteFlags) -> Result<MapWrite<T, B>>{
self.buffer
.borrow_mut()
.map_range_write(self.range.start, self.range.end - self.range.start, flags)
}
pub fn map_read_write(&mut self, flags: MapReadWriteFlags) -> Result<MapReadWrite<T, B>>{
self.buffer
.borrow_mut()
.map_range_read_write(self.range.start, self.range.end - self.range.start, flags)
}
}
#[cfg(not(feature="webgl"))]
impl<T: 'static, B: WithMapRangeMut<T>, BB: BorrowMut<B>> Range<T,B,BB>{
pub unsafe fn with_map_write<F: FnMut(&mut [T])>(&mut self, flags: MapWriteFlags, f: F) -> Result<()>{
self.buffer
.borrow_mut()
.with_map_range_write(self.range.start, self.range.end - self.range.start, flags, f)
}
pub fn with_map_read_write<F: FnMut(&mut [T])>(&mut self, flags: MapReadWriteFlags, f: F) -> Result<()>{
self.buffer
.borrow_mut()
.with_map_range_read_write(self.range.start, self.range.end - self.range.start, flags, f)
}
}
#[cfg(not(feature="webgl"))]
impl<T: 'static, B: TypedBuffer<T> + WithBackend + WithMapRange<T>, BB: Borrow<B> + Clone> Range<T,B,BB>{
pub fn range<R: InputRange>(&self, range: R) -> Range<T, B, BB>{
Range{
buffer: self.buffer.clone(),
range: range.to_range(self),
marker_type: PhantomData,
marker_buffer: PhantomData,
}
}
}
#[cfg(feature="webgl")]
impl<T: 'static, B: TypedBuffer<T> + WithBackend + Clone, BB: Borrow<B> + Clone> Range<T,B,BB>{
pub fn range<R: InputRange>(&self, range: R) -> Range<T, B, BB>{
Range{
buffer: self.buffer.clone(),
range: range.to_range(self),
marker_type: PhantomData,
marker_buffer: PhantomData,
}
}
}
impl<T: 'static, B: TypedBuffer<T> + WithBackend, BB: Borrow<B>> Range<T,B,BB>{
pub fn copy_to<U, BR: BufferRange<U> + WithBackendMut>(&self, dst: &mut BR){
self.buffer.borrow().with_backend(|src_bk|{
let offset = dst.start() * (dst as &BR).stride();
dst.with_backend_mut(|dst_bk|
src_bk.copy_to(dst_bk, self.range.start, offset, self.capacity_bytes())
);
});
}
}
impl<T: 'static, B: BufferRangeMut<T> + WithBackendMut, BB: BorrowMut<B>> Range<T,B,BB>{
pub fn update(&mut self, data: &[T]){
let offset = self.start() * self.stride();
let bytes = mem::size_of_val(data);
debug_assert!(bytes <= self.capacity_bytes());
unsafe{
let data = data.as_ptr() as *const _;
self.with_backend_mut(|backend| backend.update(data, bytes, offset));
}
}
}
#[cfg(not(feature="webgl"))]
impl<T: 'static, B: TypedBuffer<T> + WithMapRange<T> + WithBackend, BB: Borrow<B>> TypedBuffer<T> for Range<T,B,BB>{
fn id(&self) -> GLuint{
(*self).id()
}
fn len(&self) -> usize{
(*self).len()
}
fn capacity(&self) -> usize{
(*self).capacity()
}
fn with_map_read<F: FnMut(&[T])>(&self, flags: MapReadFlags, f: F) -> Result<()>{
(*self).with_map_read(flags, f)
}
fn copy_to<U,BR:BufferRange<U> + WithBackendMut>(&self, dst: &mut BR){
(*self).copy_to(dst)
}
#[cfg(not(feature="webgl"))]
unsafe fn unmap(&self){
self.buffer.borrow().unmap()
}
}
#[cfg(feature="webgl")]
impl<T: 'static, B: TypedBuffer<T> + WithBackend, BB: Borrow<B>> TypedBuffer<T> for Range<T,B,BB>{
fn id(&self) -> GLuint{
(*self).id()
}
fn len(&self) -> usize{
(*self).len()
}
fn capacity(&self) -> usize{
(*self).capacity()
}
fn copy_to<U,BR:BufferRange<U> + WithBackendMut>(&self, dst: &mut BR){
(*self).copy_to(dst)
}
}
#[cfg(not(feature="webgl"))]
impl<'a, T: 'static, B: TypedBuffer<T> + WithMapRangeMut<T> + WithBackend, BB: BorrowMut<B>> TypedBufferMut<T> for Range<T,B,BB> {
#[cfg(not(feature="webgl"))]
unsafe fn with_map_write<F: FnMut(&mut [T])>(&mut self, flags: MapWriteFlags, f: F) -> Result<()>{
self.with_map_write(flags, f)
}
#[cfg(not(feature="webgl"))]
fn with_map_read_write<F: FnMut(&mut [T])>(&mut self, flags: MapReadWriteFlags, f: F) -> Result<()>{
self.with_map_read_write(flags, f)
}
}
#[cfg(feature="webgl")]
impl<'a, T: 'static, B: TypedBuffer<T> + WithBackend, BB: BorrowMut<B>> TypedBufferMut<T> for Range<T,B,BB> {}
#[cfg(not(feature="webgl"))]
impl<T: 'static, B: TypedBuffer<T> + WithMapRange<T> + WithBackend, BB: Borrow<B>> BufferRange<T> for Range<T,B,BB>{
fn start(&self) -> usize{
(*self).start()
}
fn end(&self) -> usize{
(*self).end()
}
fn into_range<R: InputRange>(self, range: R) -> super::Range<T, Self, Self> where Self: Sized{
Range{
range: range.to_range(&self),
buffer: self,
marker_type: PhantomData,
marker_buffer: PhantomData,
}
}
}
#[cfg(feature="webgl")]
impl<T: 'static, B: TypedBuffer<T> + WithBackend, BB: Borrow<B>> BufferRange<T> for Range<T,B,BB>{
fn start(&self) -> usize{
(*self).start()
}
fn end(&self) -> usize{
(*self).end()
}
fn into_range<R: InputRange>(self, range: R) -> super::Range<T, Self, Self> where Self: Sized{
Range{
range: range.to_range(&self),
buffer: self,
marker_type: PhantomData,
marker_buffer: PhantomData,
}
}
}
#[cfg(not(feature="webgl"))]
impl<T:'static, B:BufferRangeMut<T> + WithMapRange<T> + WithBackend + WithBackendMut, BB: BorrowMut<B>> BufferRangeMut<T> for Range<T,B,BB>{
fn update(&mut self, data: &[T]){
self.update(data);
}
}
#[cfg(feature="webgl")]
impl<T:'static, B:BufferRangeMut<T> + WithBackend + WithBackendMut, BB: BorrowMut<B>> BufferRangeMut<T> for Range<T,B,BB>{
fn update(&mut self, data: &[T]){
self.update(data);
}
}
#[cfg(not(feature="webgl"))]
impl<T: 'static, B: WithMapRange<T>,BB:Borrow<B>> WithMapRange<T> for Range<T,B,BB>{
fn with_map_range_read<F: FnMut(&[T])>(&self, offset: usize, length: usize, flags: MapReadFlags, f: F) -> Result<()>{
self.buffer
.borrow()
.with_map_range_read(self.range.start + offset, length, flags, f)
}
}
#[cfg(not(feature="webgl"))]
impl<T: 'static, B: WithMapRangeMut<T>, BB:BorrowMut<B>> WithMapRangeMut<T> for Range<T,B,BB>{
unsafe fn with_map_range_write<F: FnMut(&mut [T])>(&mut self, offset: usize, length: usize, flags: MapWriteFlags, f: F) -> Result<()>{
self.buffer
.borrow_mut()
.with_map_range_write(self.range.start + offset, length, flags, f)
}
fn with_map_range_read_write<F: FnMut(&mut [T])>(&mut self, offset: usize, length: usize, flags: MapReadWriteFlags, f: F) -> Result<()>{
self.buffer
.borrow_mut()
.with_map_range_read_write(self.range.start + offset, length, flags, f)
}
}
impl<T, B:WithBackend,BB:Borrow<B>> WithBackend for Range<T,B,BB>{
fn with_backend<F:FnMut(&dyn Backend)->R, R>(&self, f:F) -> R{
self.buffer.borrow().with_backend(f)
}
}
impl<T, B:WithBackendMut, BB:BorrowMut<B>> WithBackendMut for Range<T,B,BB>{
fn with_backend_mut<F:FnMut(&mut dyn Backend)->R, R>(&mut self, f:F) -> R{
self.buffer.borrow_mut().with_backend_mut(f)
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T,B,BB> MapPersistent<T> for Range<T,B,BB>
where T: 'static,
B: MapPersistentRange<T>,
BB: Borrow<B>,
for<'a> &'a B: TypedBuffer<T>,
Self: TypedBuffer<T>,
for<'a> &'a Self: TypedBuffer<T>,
{
fn map_persistent_read(&self, flags: MapReadFlags) -> Result<MapPersistentRead<T,&Self>>{
let map = unsafe{
self.buffer.borrow().unsafe_map_range_persistent_read(Some(self.range.clone()), flags)?
};
Ok(MapPersistentRead::new(map, self))
}
fn into_map_persistent_read(self, flags: MapReadFlags) -> Result<MapPersistentRead<T,Self>> where Self: Sized{
let map = unsafe{
self.buffer.borrow().unsafe_map_range_persistent_read(Some(self.range.clone()), flags)?
};
Ok(MapPersistentRead::new(map, self))
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T,B,BB> MapPersistentMut<T> for Range<T,B,BB>
where T: 'static,
B: MapPersistentRangeMut<T>,
BB: Borrow<B>,
for<'a> &'a B: TypedBuffer<T>,
Self: TypedBuffer<T>,
for<'a> &'a Self: TypedBuffer<T>,
{
fn map_persistent_write(&self, flags: MapWriteFlags) -> Result<MapPersistentWrite<T,&Self>>{
let map = unsafe{
self.buffer.borrow().unsafe_map_range_persistent_write(Some(self.range.clone()), flags)?
};
Ok(MapPersistentWrite::new(map, self))
}
fn map_persistent_read_write(&self, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T,&Self>>{
let map = unsafe{
self.buffer.borrow().unsafe_map_range_persistent_read_write(Some(self.range.clone()), flags)?
};
Ok(MapPersistentReadWrite::new(map, self))
}
fn into_map_persistent_write(self, flags: MapWriteFlags) -> Result<MapPersistentWrite<T,Self>>{
let map = unsafe{
self.buffer.borrow().unsafe_map_range_persistent_write(Some(self.range.clone()), flags)?
};
Ok(MapPersistentWrite::new(map, self))
}
fn into_map_persistent_read_write(self, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T,Self>>{
let map = unsafe{
self.buffer.borrow().unsafe_map_range_persistent_read_write(Some(self.range.clone()), flags)?
};
Ok(MapPersistentReadWrite::new(map, self))
}
}