use super::DrawData;
use crate::sys;
use crate::texture::TextureData;
use std::marker::PhantomData;
impl DrawData {
pub fn textures(&self) -> TextureIterator<'_> {
unsafe {
if self.textures.is_null() {
TextureIterator::new(std::ptr::null(), std::ptr::null())
} else {
let vector = &*self.textures;
if vector.size <= 0 || vector.data.is_null() {
TextureIterator::new(std::ptr::null(), std::ptr::null())
} else {
TextureIterator::new(vector.data, vector.data.add(vector.size as usize))
}
}
}
}
pub fn textures_mut(&mut self) -> TextureMutCursor<'_> {
unsafe {
if self.textures.is_null() {
TextureMutCursor::new(std::ptr::null_mut(), std::ptr::null_mut())
} else {
let vector = &mut *self.textures;
if vector.size <= 0 || vector.data.is_null() {
TextureMutCursor::new(std::ptr::null_mut(), std::ptr::null_mut())
} else {
TextureMutCursor::new(vector.data, vector.data.add(vector.size as usize))
}
}
}
}
pub fn textures_count(&self) -> usize {
unsafe {
if self.textures.is_null() {
0
} else {
let vector = &*self.textures;
if vector.size <= 0 || vector.data.is_null() {
0
} else {
vector.size as usize
}
}
}
}
pub fn texture(&self, index: usize) -> Option<&TextureData> {
unsafe {
if self.textures.is_null() {
return None;
}
let vector = &*self.textures;
let size = usize::try_from(vector.size).ok()?;
if size == 0 || vector.data.is_null() {
return None;
}
if index >= size {
return None;
}
let texture_ptr = *vector.data.add(index);
if texture_ptr.is_null() {
return None;
}
Some(TextureData::from_raw_ref(texture_ptr as *const _))
}
}
pub fn texture_mut(&mut self, index: usize) -> Option<&mut TextureData> {
unsafe {
if self.textures.is_null() {
return None;
}
let vector = &*self.textures;
let size = usize::try_from(vector.size).ok()?;
if size == 0 || vector.data.is_null() {
return None;
}
if index >= size {
return None;
}
let texture_ptr = *vector.data.add(index);
if texture_ptr.is_null() {
return None;
}
Some(TextureData::from_raw(texture_ptr))
}
}
}
pub struct TextureIterator<'a> {
ptr: *const *mut sys::ImTextureData,
end: *const *mut sys::ImTextureData,
_phantom: PhantomData<&'a TextureData>,
}
impl<'a> TextureIterator<'a> {
pub(crate) unsafe fn new(
ptr: *const *mut sys::ImTextureData,
end: *const *mut sys::ImTextureData,
) -> Self {
Self {
ptr,
end,
_phantom: PhantomData,
}
}
}
impl<'a> Iterator for TextureIterator<'a> {
type Item = &'a TextureData;
fn next(&mut self) -> Option<Self::Item> {
while self.ptr < self.end {
let texture_ptr = unsafe { *self.ptr };
self.ptr = unsafe { self.ptr.add(1) };
if texture_ptr.is_null() {
continue;
}
return Some(unsafe { TextureData::from_raw_ref(texture_ptr as *const _) });
}
None
}
}
impl<'a> std::iter::FusedIterator for TextureIterator<'a> {}
pub struct TextureMutCursor<'a> {
ptr: *mut *mut sys::ImTextureData,
end: *mut *mut sys::ImTextureData,
_phantom: PhantomData<&'a mut TextureData>,
}
impl<'a> TextureMutCursor<'a> {
pub(crate) unsafe fn new(
ptr: *mut *mut sys::ImTextureData,
end: *mut *mut sys::ImTextureData,
) -> Self {
Self {
ptr,
end,
_phantom: PhantomData,
}
}
pub fn next(&mut self) -> Option<TextureDataMut<'_>> {
while self.ptr < self.end {
let texture_ptr = unsafe { *self.ptr };
self.ptr = unsafe { self.ptr.add(1) };
if texture_ptr.is_null() {
continue;
}
return Some(TextureDataMut {
raw: texture_ptr,
_phantom: PhantomData,
});
}
None
}
}
pub struct TextureDataMut<'a> {
raw: *mut sys::ImTextureData,
_phantom: PhantomData<&'a mut TextureData>,
}
impl std::ops::Deref for TextureDataMut<'_> {
type Target = TextureData;
fn deref(&self) -> &Self::Target {
unsafe { TextureData::from_raw_ref(self.raw as *const _) }
}
}
impl std::ops::DerefMut for TextureDataMut<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { TextureData::from_raw(self.raw) }
}
}