Skip to main content

mtl_gpu/mtl4/
pipeline_data_set_serializer.rs

1//! MTL4 PipelineDataSetSerializer implementation.
2//!
3//! Corresponds to `Metal/MTL4PipelineDataSetSerializer.hpp`.
4
5use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::Referencing;
9use mtl_sys::{msg_send_0, msg_send_1, msg_send_2, sel};
10
11use super::enums::PipelineDataSetSerializerConfiguration;
12
13// ============================================================
14// PipelineDataSetSerializerDescriptor
15// ============================================================
16
17/// Descriptor for creating a pipeline data set serializer.
18///
19/// C++ equivalent: `MTL4::PipelineDataSetSerializerDescriptor`
20#[repr(transparent)]
21pub struct PipelineDataSetSerializerDescriptor(NonNull<c_void>);
22
23impl PipelineDataSetSerializerDescriptor {
24    /// Create a PipelineDataSetSerializerDescriptor from a raw pointer.
25    #[inline]
26    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
27        NonNull::new(ptr).map(Self)
28    }
29
30    /// Get the raw pointer.
31    #[inline]
32    pub fn as_raw(&self) -> *mut c_void {
33        self.0.as_ptr()
34    }
35
36    /// Create a new pipeline data set serializer descriptor.
37    pub fn new() -> Option<Self> {
38        unsafe {
39            let class = mtl_sys::Class::get("MTL4PipelineDataSetSerializerDescriptor")?;
40            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
41            if ptr.is_null() {
42                return None;
43            }
44            let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
45            Self::from_raw(ptr)
46        }
47    }
48
49    /// Get the configuration.
50    ///
51    /// C++ equivalent: `PipelineDataSetSerializerConfiguration configuration() const`
52    pub fn configuration(&self) -> PipelineDataSetSerializerConfiguration {
53        unsafe { msg_send_0(self.as_ptr(), sel!(configuration)) }
54    }
55
56    /// Set the configuration.
57    ///
58    /// C++ equivalent: `void setConfiguration(MTL4::PipelineDataSetSerializerConfiguration)`
59    pub fn set_configuration(&self, configuration: PipelineDataSetSerializerConfiguration) {
60        unsafe {
61            let _: () = msg_send_1(self.as_ptr(), sel!(setConfiguration:), configuration);
62        }
63    }
64}
65
66impl Clone for PipelineDataSetSerializerDescriptor {
67    fn clone(&self) -> Self {
68        unsafe {
69            mtl_sys::msg_send_0::<*mut c_void>(self.as_ptr(), mtl_sys::sel!(retain));
70        }
71        Self(self.0)
72    }
73}
74
75impl Drop for PipelineDataSetSerializerDescriptor {
76    fn drop(&mut self) {
77        unsafe {
78            mtl_sys::msg_send_0::<()>(self.as_ptr(), mtl_sys::sel!(release));
79        }
80    }
81}
82
83impl Referencing for PipelineDataSetSerializerDescriptor {
84    #[inline]
85    fn as_ptr(&self) -> *const c_void {
86        self.0.as_ptr()
87    }
88}
89
90unsafe impl Send for PipelineDataSetSerializerDescriptor {}
91unsafe impl Sync for PipelineDataSetSerializerDescriptor {}
92
93impl std::fmt::Debug for PipelineDataSetSerializerDescriptor {
94    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95        f.debug_struct("PipelineDataSetSerializerDescriptor")
96            .field("configuration", &self.configuration())
97            .finish()
98    }
99}
100
101// ============================================================
102// PipelineDataSetSerializer
103// ============================================================
104
105/// Serializes pipeline data sets for caching.
106///
107/// C++ equivalent: `MTL4::PipelineDataSetSerializer`
108///
109/// PipelineDataSetSerializer captures pipeline creation data for
110/// later serialization to disk or as a pipelines script.
111#[repr(transparent)]
112pub struct PipelineDataSetSerializer(NonNull<c_void>);
113
114impl PipelineDataSetSerializer {
115    /// Create a PipelineDataSetSerializer from a raw pointer.
116    #[inline]
117    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
118        NonNull::new(ptr).map(Self)
119    }
120
121    /// Get the raw pointer.
122    #[inline]
123    pub fn as_raw(&self) -> *mut c_void {
124        self.0.as_ptr()
125    }
126
127    /// Serialize as an archive and flush to a URL.
128    ///
129    /// C++ equivalent: `bool serializeAsArchiveAndFlushToURL(const NS::URL*, NS::Error**)`
130    ///
131    /// Returns `Ok(true)` on success, `Err` with the error on failure.
132    pub fn serialize_as_archive_and_flush_to_url(
133        &self,
134        url: *const c_void,
135    ) -> Result<bool, mtl_foundation::Error> {
136        unsafe {
137            let mut error: *mut c_void = std::ptr::null_mut();
138            let result: bool = msg_send_2(
139                self.as_ptr(),
140                sel!(serializeAsArchiveAndFlushToURL:error:),
141                url,
142                &mut error as *mut _,
143            );
144            if !error.is_null() {
145                if let Some(err) = mtl_foundation::Error::from_ptr(error) {
146                    return Err(err);
147                }
148            }
149            Ok(result)
150        }
151    }
152
153    /// Serialize as a pipelines script.
154    ///
155    /// C++ equivalent: `NS::Data* serializeAsPipelinesScript(NS::Error**)`
156    ///
157    /// Returns the serialized data on success, or an error on failure.
158    pub fn serialize_as_pipelines_script(&self) -> Result<*mut c_void, mtl_foundation::Error> {
159        unsafe {
160            let mut error: *mut c_void = std::ptr::null_mut();
161            let data: *mut c_void = msg_send_1(
162                self.as_ptr(),
163                sel!(serializeAsPipelinesScriptWithError:),
164                &mut error as *mut _,
165            );
166            if !error.is_null() {
167                if let Some(err) = mtl_foundation::Error::from_ptr(error) {
168                    return Err(err);
169                }
170            }
171            Ok(data)
172        }
173    }
174}
175
176impl Clone for PipelineDataSetSerializer {
177    fn clone(&self) -> Self {
178        unsafe {
179            mtl_sys::msg_send_0::<*mut c_void>(self.as_ptr(), mtl_sys::sel!(retain));
180        }
181        Self(self.0)
182    }
183}
184
185impl Drop for PipelineDataSetSerializer {
186    fn drop(&mut self) {
187        unsafe {
188            mtl_sys::msg_send_0::<()>(self.as_ptr(), mtl_sys::sel!(release));
189        }
190    }
191}
192
193impl Referencing for PipelineDataSetSerializer {
194    #[inline]
195    fn as_ptr(&self) -> *const c_void {
196        self.0.as_ptr()
197    }
198}
199
200unsafe impl Send for PipelineDataSetSerializer {}
201unsafe impl Sync for PipelineDataSetSerializer {}
202
203impl std::fmt::Debug for PipelineDataSetSerializer {
204    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
205        f.debug_struct("PipelineDataSetSerializer").finish()
206    }
207}
208
209#[cfg(test)]
210mod tests {
211    use super::*;
212
213    #[test]
214    fn test_pipeline_data_set_serializer_descriptor_size() {
215        assert_eq!(
216            std::mem::size_of::<PipelineDataSetSerializerDescriptor>(),
217            std::mem::size_of::<*mut c_void>()
218        );
219    }
220
221    #[test]
222    fn test_pipeline_data_set_serializer_size() {
223        assert_eq!(
224            std::mem::size_of::<PipelineDataSetSerializer>(),
225            std::mem::size_of::<*mut c_void>()
226        );
227    }
228}