Skip to main content

mtl_gpu/argument/
struct_type.rs

1//! A struct type for reflection.
2
3use std::ffi::c_void;
4use std::ptr::NonNull;
5
6use mtl_foundation::Referencing;
7use mtl_sys::{msg_send_0, msg_send_1, sel};
8
9use crate::enums::DataType;
10
11use super::StructMember;
12
13/// A struct type for reflection.
14///
15/// C++ equivalent: `MTL::StructType`
16#[repr(transparent)]
17pub struct StructType(pub(crate) NonNull<c_void>);
18
19impl StructType {
20    /// Create from a raw pointer.
21    ///
22    /// # Safety
23    ///
24    /// The pointer must be a valid Metal StructType.
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    /// Get the data type.
37    ///
38    /// C++ equivalent: `DataType dataType() const`
39    #[inline]
40    pub fn data_type(&self) -> DataType {
41        unsafe { msg_send_0(self.as_ptr(), sel!(dataType)) }
42    }
43
44    /// Get a member by name.
45    ///
46    /// C++ equivalent: `StructMember* memberByName(const NS::String*)`
47    pub fn member_by_name(&self, name: &str) -> Option<StructMember> {
48        let ns_name = mtl_foundation::String::from_str(name)?;
49        unsafe {
50            let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(memberByName:), ns_name.as_ptr());
51            StructMember::from_raw(ptr)
52        }
53    }
54
55    /// Get the members as a raw NS::Array pointer.
56    ///
57    /// C++ equivalent: `NS::Array* members() const`
58    #[inline]
59    pub fn members_ptr(&self) -> *const c_void {
60        unsafe { msg_send_0(self.as_ptr(), sel!(members)) }
61    }
62}
63
64impl Clone for StructType {
65    fn clone(&self) -> Self {
66        unsafe {
67            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
68        }
69        Self(self.0)
70    }
71}
72
73impl Drop for StructType {
74    fn drop(&mut self) {
75        unsafe {
76            msg_send_0::<()>(self.as_ptr(), sel!(release));
77        }
78    }
79}
80
81impl Referencing for StructType {
82    #[inline]
83    fn as_ptr(&self) -> *const c_void {
84        self.0.as_ptr()
85    }
86}
87
88unsafe impl Send for StructType {}
89unsafe impl Sync for StructType {}