use super::*;
use std::any::Any;
#[derive(Clone, Copy, Debug)]
pub struct PreRenderExtra {
pub(crate) in_data_ptr: *const ae_sys::PF_InData,
pub(crate) ptr: *mut ae_sys::PF_PreRenderExtra,
}
impl AsRef<ae_sys::PF_PreRenderExtra> for PreRenderExtra {
fn as_ref(&self) -> &ae_sys::PF_PreRenderExtra {
unsafe { &*self.ptr }
}
}
impl AsMut<ae_sys::PF_PreRenderExtra> for PreRenderExtra {
fn as_mut(&mut self) -> &mut ae_sys::PF_PreRenderExtra {
unsafe { &mut *self.ptr }
}
}
impl PreRenderExtra {
pub fn from_raw(
in_data_ptr: *const ae_sys::PF_InData,
ptr: *mut ae_sys::PF_PreRenderExtra,
) -> Self {
assert!(!in_data_ptr.is_null());
assert!(!ptr.is_null());
Self { in_data_ptr, ptr }
}
pub fn as_ptr(&self) -> *mut ae_sys::PF_PreRenderExtra {
self.ptr
}
pub fn what_gpu(&self) -> GpuFramework {
assert!(!self.as_ref().input.is_null());
unsafe { (*self.as_ref().input).what_gpu.into() }
}
pub fn bit_depth(&self) -> i16 {
assert!(!self.as_ref().input.is_null());
unsafe { (*self.as_ref().input).bitdepth as i16 }
}
pub fn device_index(&self) -> usize {
assert!(!self.as_ref().input.is_null());
unsafe { (*self.as_ref().input).device_index as usize }
}
pub fn set_pre_render_data<T: Any>(&mut self, val: T) {
let boxed: Box<Box<dyn Any>> = Box::new(Box::new(val));
unsafe {
(*self.as_mut().output).pre_render_data =
Box::<Box<dyn Any>>::into_raw(boxed) as *mut _;
}
unsafe {
(*self.as_mut().output).delete_pre_render_data_func = Some(delete_pre_render_data);
}
}
pub fn callbacks(&self) -> PreRenderCallbacks {
unsafe { PreRenderCallbacks::from_raw(self.in_data_ptr, (*self.ptr).cb) }
}
pub fn output_request(&self) -> ae_sys::PF_RenderRequest {
assert!(!self.as_ref().input.is_null());
unsafe { (*self.as_ref().input).output_request }
}
pub fn set_gpu_render_possible(&mut self, val: bool) {
assert!(!self.as_mut().output.is_null());
unsafe {
if val {
(*self.as_mut().output).flags |=
ae_sys::PF_RenderOutputFlag_GPU_RENDER_POSSIBLE as i16;
} else {
(*self.as_mut().output).flags &=
!(ae_sys::PF_RenderOutputFlag_GPU_RENDER_POSSIBLE as i16);
}
}
}
pub fn set_returns_extra_pixels(&mut self, val: bool) {
assert!(!self.as_mut().output.is_null());
unsafe {
if val {
(*self.as_mut().output).flags |=
ae_sys::PF_RenderOutputFlag_RETURNS_EXTRA_PIXELS as i16;
} else {
(*self.as_mut().output).flags &=
!(ae_sys::PF_RenderOutputFlag_RETURNS_EXTRA_PIXELS as i16);
}
}
}
pub fn result_rect(&self) -> Rect {
assert!(!self.as_ref().output.is_null());
unsafe { (*self.as_ref().output).result_rect.into() }
}
pub fn max_result_rect(&self) -> Rect {
assert!(!self.as_ref().output.is_null());
unsafe { (*self.as_ref().output).max_result_rect.into() }
}
pub fn set_result_rect(&mut self, rect: Rect) {
assert!(!self.as_mut().output.is_null());
unsafe {
(*self.as_mut().output).result_rect = rect.into();
}
}
pub fn set_max_result_rect(&mut self, rect: Rect) {
assert!(!self.as_mut().output.is_null());
unsafe {
(*self.as_mut().output).max_result_rect = rect.into();
}
}
pub fn union_result_rect(&mut self, rect: Rect) -> Rect {
let rect = *self.result_rect().union(&rect);
self.set_result_rect(rect);
rect
}
pub fn union_max_result_rect(&mut self, rect: Rect) -> Rect {
let rect = *self.max_result_rect().union(&rect);
self.set_max_result_rect(rect);
rect
}
}
unsafe extern "C" fn delete_pre_render_data(data: *mut std::ffi::c_void) {
if !data.is_null() {
let _ = unsafe { Box::<Box<dyn Any>>::from_raw(data as *mut _) };
}
}
#[derive(Clone, Copy, Debug)]
pub struct SmartRenderExtra {
pub(crate) in_data_ptr: *const ae_sys::PF_InData,
pub(crate) ptr: *mut ae_sys::PF_SmartRenderExtra,
}
impl AsRef<ae_sys::PF_SmartRenderExtra> for SmartRenderExtra {
fn as_ref(&self) -> &ae_sys::PF_SmartRenderExtra {
unsafe { &*self.ptr }
}
}
impl SmartRenderExtra {
pub fn from_raw(
in_data_ptr: *const ae_sys::PF_InData,
ptr: *mut ae_sys::PF_SmartRenderExtra,
) -> Self {
assert!(!ptr.is_null());
Self { in_data_ptr, ptr }
}
pub fn as_ptr(&self) -> *mut ae_sys::PF_SmartRenderExtra {
self.ptr
}
pub fn callbacks(&self) -> SmartRenderCallbacks {
unsafe { SmartRenderCallbacks::from_raw(self.in_data_ptr, (*self.ptr).cb) }
}
pub fn what_gpu(&self) -> GpuFramework {
assert!(!self.as_ref().input.is_null());
unsafe { (*self.as_ref().input).what_gpu.into() }
}
pub fn device_index(&self) -> usize {
assert!(!self.as_ref().input.is_null());
unsafe { (*self.as_ref().input).device_index as usize }
}
pub fn bit_depth(&self) -> i16 {
assert!(!self.as_ref().input.is_null());
unsafe { (*self.as_ref().input).bitdepth }
}
pub fn gpu_data<T: Any>(&self) -> Option<&T> {
assert!(!self.as_ref().input.is_null());
if unsafe { (*(*self.ptr).input).gpu_data.is_null() } {
return None;
}
let data =
unsafe { Box::<Box<dyn Any>>::from_raw((*(*self.ptr).input).gpu_data as *mut _) };
let data = Box::<Box<dyn Any>>::leak(data);
match data.downcast_ref::<T>() {
Some(data) => Some(data),
None => panic!("Invalid type for gpu_data"),
}
}
pub fn pre_render_data<T: Any>(&self) -> Option<&T> {
assert!(!self.as_ref().input.is_null());
if unsafe { (*(*self.ptr).input).pre_render_data.is_null() } {
return None;
}
let data = unsafe {
Box::<Box<dyn Any>>::from_raw((*(*self.ptr).input).pre_render_data as *mut _)
};
let data = Box::<Box<dyn Any>>::leak(data);
match data.downcast_ref::<T>() {
Some(data) => Some(data),
None => panic!("Invalid type for pre_render_data"),
}
}
pub fn pre_render_data_mut<T: Any>(&mut self) -> Option<&mut T> {
assert!(!self.as_ref().input.is_null());
if unsafe { (*(*self.ptr).input).pre_render_data.is_null() } {
return None;
}
let data = unsafe {
Box::<Box<dyn Any>>::from_raw((*(*self.ptr).input).pre_render_data as *mut _)
};
let data = Box::<Box<dyn Any>>::leak(data);
match data.downcast_mut::<T>() {
Some(data) => Some(data),
None => panic!("Invalid type for pre_render_data"),
}
}
}
#[derive(Copy, Clone, Debug)]
pub struct PreRenderCallbacks {
pub(crate) in_data_ptr: *const ae_sys::PF_InData,
pub(crate) rc_ptr: *const ae_sys::PF_PreRenderCallbacks,
}
impl PreRenderCallbacks {
pub fn from_raw(
in_data_ptr: *const ae_sys::PF_InData,
rc_ptr: *const ae_sys::PF_PreRenderCallbacks,
) -> Self {
Self {
in_data_ptr,
rc_ptr,
}
}
pub fn as_ptr(&self) -> *const ae_sys::PF_PreRenderCallbacks {
self.rc_ptr
}
pub fn guid_mix_in_ptr<T>(
&self,
buf: &T,
) -> Result<(), Error> {
let buf_ptr: *const std::ffi::c_void = buf as *const _ as *const std::ffi::c_void;
if buf_ptr.is_null() {
return Err(Error::InvalidCallback);
}
let buf_size = std::mem::size_of_val(buf);
if buf_size == 0 {
return Err(Error::InvalidCallback);
}
if let Some(guid_mix_in_ptr) = unsafe { *self.rc_ptr }.GuidMixInPtr {
match unsafe { guid_mix_in_ptr((*self.in_data_ptr).effect_ref, buf_size as u32, buf_ptr) } {
0 => Ok(()),
e => Err(Error::from(e)),
}
} else {
Err(Error::InvalidCallback)
}
}
pub fn checkout_layer(
&self,
index: i32,
checkout_id: i32,
req: &ae_sys::PF_RenderRequest,
what_time: i32,
time_step: i32,
time_scale: u32,
) -> Result<ae_sys::PF_CheckoutResult, Error> {
if let Some(checkout_layer) = unsafe { *self.rc_ptr }.checkout_layer {
let mut checkout_result = std::mem::MaybeUninit::<ae_sys::PF_CheckoutResult>::uninit();
match unsafe {
checkout_layer(
(*self.in_data_ptr).effect_ref,
index,
checkout_id,
req,
what_time,
time_step,
time_scale,
checkout_result.as_mut_ptr(),
)
} {
0 => Ok(unsafe { checkout_result.assume_init() }),
e => Err(Error::from(e)),
}
} else {
Err(Error::InvalidCallback)
}
}
}
#[derive(Copy, Clone, Debug)]
pub struct SmartRenderCallbacks {
pub(crate) in_data_ptr: *const ae_sys::PF_InData,
pub(crate) rc_ptr: *const ae_sys::PF_SmartRenderCallbacks,
}
impl SmartRenderCallbacks {
pub fn from_raw(
in_data_ptr: *const ae_sys::PF_InData,
rc_ptr: *const ae_sys::PF_SmartRenderCallbacks,
) -> Self {
Self {
in_data_ptr,
rc_ptr,
}
}
pub fn as_ptr(&self) -> *const ae_sys::PF_SmartRenderCallbacks {
self.rc_ptr
}
pub fn checkout_layer_pixels(&self, checkout_id: u32) -> Result<Option<Layer>, Error> {
if let Some(checkout_layer_pixels) = unsafe { *self.rc_ptr }.checkout_layer_pixels {
let mut effect_world_ptr = std::ptr::null_mut();
match (unsafe {
checkout_layer_pixels(
(*self.in_data_ptr).effect_ref,
checkout_id as i32,
&mut effect_world_ptr,
)
}, effect_world_ptr.is_null()) {
(0, false) => Ok(Some(Layer::from_raw(
effect_world_ptr,
self.in_data_ptr,
None,
))),
(0, true) => Ok(None),
(e, _) => Err(Error::from(e)),
}
} else {
Err(Error::InvalidCallback)
}
}
pub fn checkin_layer_pixels(&self, checkout_id: u32) -> Result<(), Error> {
if let Some(checkin_layer_pixels) = unsafe { *self.rc_ptr }.checkin_layer_pixels {
match unsafe {
checkin_layer_pixels((*self.in_data_ptr).effect_ref, checkout_id as i32)
} {
0 => Ok(()),
e => Err(Error::from(e)),
}
} else {
Err(Error::InvalidCallback)
}
}
pub fn checkout_output(&self) -> Result<Option<Layer>, Error> {
if let Some(checkout_output) = unsafe { *self.rc_ptr }.checkout_output {
let mut effect_world_ptr = std::ptr::null_mut();
match (unsafe {
checkout_output(
(*self.in_data_ptr).effect_ref,
&mut effect_world_ptr,
)
}, effect_world_ptr.is_null()) {
(0, false) => Ok(Some(Layer::from_raw(
effect_world_ptr,
self.in_data_ptr,
None,
))),
(0, true) => Ok(None),
(e, _) => Err(Error::from(e)),
}
} else {
Err(Error::InvalidCallback)
}
}
}