Skip to main content

mtl_gpu/acceleration/
motion_keyframe.rs

1//! Motion keyframe data types.
2//!
3//! Contains `MotionKeyframeData`.
4
5use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::{Referencing, UInteger};
9use mtl_sys::{msg_send_0, msg_send_1, sel};
10
11use crate::Buffer;
12
13pub struct MotionKeyframeData(pub(crate) NonNull<c_void>);
14
15impl MotionKeyframeData {
16    /// Create new motion keyframe data.
17    ///
18    /// C++ equivalent: `static MotionKeyframeData* alloc()->init()`
19    pub fn new() -> Option<Self> {
20        unsafe {
21            let class = mtl_sys::Class::get("MTLMotionKeyframeData")?;
22            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
23            if ptr.is_null() {
24                return None;
25            }
26            let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
27            Self::from_raw(ptr)
28        }
29    }
30
31    /// Create motion keyframe data using the class method.
32    ///
33    /// C++ equivalent: `static MotionKeyframeData* data()`
34    pub fn data() -> Option<Self> {
35        unsafe {
36            let class = mtl_sys::Class::get("MTLMotionKeyframeData")?;
37            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(data));
38            if ptr.is_null() {
39                return None;
40            }
41            // The returned object is autoreleased, so retain it
42            let _: *mut c_void = msg_send_0(ptr, sel!(retain));
43            Self::from_raw(ptr)
44        }
45    }
46
47    /// Create from a raw pointer.
48    ///
49    /// # Safety
50    ///
51    /// The pointer must be a valid Metal motion keyframe data object.
52    #[inline]
53    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
54        NonNull::new(ptr).map(Self)
55    }
56
57    /// Get the raw pointer.
58    #[inline]
59    pub fn as_raw(&self) -> *mut c_void {
60        self.0.as_ptr()
61    }
62
63    /// Get the buffer.
64    ///
65    /// C++ equivalent: `Buffer* buffer() const`
66    pub fn buffer(&self) -> Option<Buffer> {
67        unsafe {
68            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(buffer));
69            if ptr.is_null() {
70                return None;
71            }
72            let _: *mut c_void = msg_send_0(ptr, sel!(retain));
73            Buffer::from_raw(ptr)
74        }
75    }
76
77    /// Set the buffer.
78    ///
79    /// C++ equivalent: `void setBuffer(Buffer*)`
80    pub fn set_buffer(&self, buffer: Option<&Buffer>) {
81        unsafe {
82            msg_send_1::<(), *const c_void>(
83                self.as_ptr(),
84                sel!(setBuffer:),
85                buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
86            );
87        }
88    }
89
90    /// Get the offset.
91    ///
92    /// C++ equivalent: `NS::UInteger offset() const`
93    #[inline]
94    pub fn offset(&self) -> UInteger {
95        unsafe { msg_send_0(self.as_ptr(), sel!(offset)) }
96    }
97
98    /// Set the offset.
99    ///
100    /// C++ equivalent: `void setOffset(NS::UInteger)`
101    #[inline]
102    pub fn set_offset(&self, offset: UInteger) {
103        unsafe {
104            msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setOffset:), offset);
105        }
106    }
107}
108
109impl Default for MotionKeyframeData {
110    fn default() -> Self {
111        Self::new().expect("failed to create motion keyframe data")
112    }
113}
114
115impl Clone for MotionKeyframeData {
116    fn clone(&self) -> Self {
117        unsafe {
118            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
119        }
120        Self(self.0)
121    }
122}
123
124impl Drop for MotionKeyframeData {
125    fn drop(&mut self) {
126        unsafe {
127            msg_send_0::<()>(self.as_ptr(), sel!(release));
128        }
129    }
130}
131
132impl Referencing for MotionKeyframeData {
133    #[inline]
134    fn as_ptr(&self) -> *const c_void {
135        self.0.as_ptr()
136    }
137}
138
139unsafe impl Send for MotionKeyframeData {}
140unsafe impl Sync for MotionKeyframeData {}