use super::{DrawData, assert_draw_list_cloneable};
use crate::internal::RawWrapper;
use crate::sys;
use std::marker::PhantomData;
use std::rc::Rc;
pub struct OwnedDrawData {
draw_data: *mut sys::ImDrawData,
_no_send_sync: PhantomData<Rc<()>>,
}
impl OwnedDrawData {
#[inline]
pub fn draw_data(&self) -> Option<&DrawData> {
if !self.draw_data.is_null() {
Some(unsafe { &*(self.draw_data as *const DrawData) })
} else {
None
}
}
}
impl Default for OwnedDrawData {
#[inline]
fn default() -> Self {
Self {
draw_data: std::ptr::null_mut(),
_no_send_sync: PhantomData,
}
}
}
impl From<&DrawData> for OwnedDrawData {
fn from(value: &DrawData) -> Self {
unsafe {
let source_ptr = RawWrapper::raw(value);
if source_ptr.CmdListsCount > 0 && !source_ptr.CmdLists.Data.is_null() {
for i in 0..(source_ptr.CmdListsCount as usize) {
let src_list = *source_ptr.CmdLists.Data.add(i);
assert_draw_list_cloneable(src_list.cast_const(), "OwnedDrawData::from");
}
}
let result = sys::ImDrawData_ImDrawData();
if result.is_null() {
panic!("Failed to allocate ImDrawData for OwnedDrawData");
}
(*result).Valid = source_ptr.Valid;
(*result).TotalIdxCount = source_ptr.TotalIdxCount;
(*result).TotalVtxCount = source_ptr.TotalVtxCount;
(*result).DisplayPos = source_ptr.DisplayPos;
(*result).DisplaySize = source_ptr.DisplaySize;
(*result).FramebufferScale = source_ptr.FramebufferScale;
(*result).OwnerViewport = source_ptr.OwnerViewport;
(*result).CmdListsCount = 0;
if source_ptr.CmdListsCount > 0 && !source_ptr.CmdLists.Data.is_null() {
for i in 0..(source_ptr.CmdListsCount as usize) {
let src_list = *source_ptr.CmdLists.Data.add(i);
if !src_list.is_null() {
let cloned = sys::ImDrawList_CloneOutput(src_list);
if !cloned.is_null() {
sys::ImDrawData_AddDrawList(result, cloned);
}
}
}
}
(*result).Textures = std::ptr::null_mut();
OwnedDrawData {
draw_data: result,
_no_send_sync: PhantomData,
}
}
}
}
impl From<&mut DrawData> for OwnedDrawData {
fn from(value: &mut DrawData) -> Self {
OwnedDrawData::from(&*value)
}
}
impl Drop for OwnedDrawData {
fn drop(&mut self) {
unsafe {
if !self.draw_data.is_null() {
if !(*self.draw_data).CmdLists.Data.is_null() {
for i in 0..(*self.draw_data).CmdListsCount as usize {
let ptr = *(*self.draw_data).CmdLists.Data.add(i);
if !ptr.is_null() {
sys::ImDrawList_destroy(ptr);
}
}
}
sys::ImDrawData_destroy(self.draw_data);
self.draw_data = std::ptr::null_mut();
}
}
}
}