Skip to main content

mtl_gpu/library/
linked_functions.rs

1//! A collection of functions to link together.
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
9/// A collection of functions to link together.
10///
11/// C++ equivalent: `MTL::LinkedFunctions`
12///
13/// Linked functions allow you to specify a set of functions that should be
14/// available for function pointers and callable from other functions.
15#[repr(transparent)]
16pub struct LinkedFunctions(pub(crate) NonNull<c_void>);
17
18impl LinkedFunctions {
19    /// Allocate a new linked functions object.
20    ///
21    /// C++ equivalent: `static LinkedFunctions* alloc()`
22    pub fn alloc() -> Option<Self> {
23        unsafe {
24            let cls = mtl_sys::Class::get("MTLLinkedFunctions")?;
25            let ptr: *mut c_void = msg_send_0(cls.as_ptr(), sel!(alloc));
26            Self::from_raw(ptr)
27        }
28    }
29
30    /// Initialize an allocated linked functions object.
31    ///
32    /// C++ equivalent: `LinkedFunctions* init()`
33    pub fn init(&self) -> Option<Self> {
34        unsafe {
35            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(init));
36            Self::from_raw(ptr)
37        }
38    }
39
40    /// Create a new linked functions object.
41    pub fn new() -> Option<Self> {
42        Self::alloc()?.init()
43    }
44
45    /// Create linked functions using the factory method.
46    ///
47    /// C++ equivalent: `static LinkedFunctions* linkedFunctions()`
48    pub fn linked_functions() -> Option<Self> {
49        unsafe {
50            let cls = mtl_sys::Class::get("MTLLinkedFunctions")?;
51            let ptr: *mut c_void = msg_send_0(cls.as_ptr(), sel!(linkedFunctions));
52            if ptr.is_null() {
53                return None;
54            }
55            msg_send_0::<*mut c_void>(ptr as *const c_void, sel!(retain));
56            Self::from_raw(ptr)
57        }
58    }
59
60    /// Create from a raw pointer.
61    ///
62    /// # Safety
63    ///
64    /// The pointer must be a valid Metal linked functions object.
65    #[inline]
66    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
67        NonNull::new(ptr).map(Self)
68    }
69
70    /// Get the raw pointer.
71    #[inline]
72    pub fn as_raw(&self) -> *mut c_void {
73        self.0.as_ptr()
74    }
75
76    /// Get the functions array (raw NSArray pointer).
77    ///
78    /// C++ equivalent: `NS::Array* functions() const`
79    pub fn functions_raw(&self) -> *mut c_void {
80        unsafe { msg_send_0(self.as_ptr(), sel!(functions)) }
81    }
82
83    /// Set the functions array.
84    ///
85    /// C++ equivalent: `void setFunctions(const NS::Array*)`
86    pub fn set_functions_raw(&self, functions: *const c_void) {
87        unsafe {
88            msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setFunctions:), functions);
89        }
90    }
91
92    /// Get the binary functions array (raw NSArray pointer).
93    ///
94    /// C++ equivalent: `NS::Array* binaryFunctions() const`
95    pub fn binary_functions_raw(&self) -> *mut c_void {
96        unsafe { msg_send_0(self.as_ptr(), sel!(binaryFunctions)) }
97    }
98
99    /// Set the binary functions array.
100    ///
101    /// C++ equivalent: `void setBinaryFunctions(const NS::Array*)`
102    pub fn set_binary_functions_raw(&self, functions: *const c_void) {
103        unsafe {
104            msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setBinaryFunctions:), functions);
105        }
106    }
107
108    /// Get the private functions array (raw NSArray pointer).
109    ///
110    /// C++ equivalent: `NS::Array* privateFunctions() const`
111    pub fn private_functions_raw(&self) -> *mut c_void {
112        unsafe { msg_send_0(self.as_ptr(), sel!(privateFunctions)) }
113    }
114
115    /// Set the private functions array.
116    ///
117    /// C++ equivalent: `void setPrivateFunctions(const NS::Array*)`
118    pub fn set_private_functions_raw(&self, functions: *const c_void) {
119        unsafe {
120            msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setPrivateFunctions:), functions);
121        }
122    }
123
124    /// Get the function groups dictionary (raw NSDictionary pointer).
125    ///
126    /// C++ equivalent: `NS::Dictionary* groups() const`
127    pub fn groups_raw(&self) -> *mut c_void {
128        unsafe { msg_send_0(self.as_ptr(), sel!(groups)) }
129    }
130
131    /// Set the function groups dictionary.
132    ///
133    /// C++ equivalent: `void setGroups(const NS::Dictionary*)`
134    pub fn set_groups_raw(&self, groups: *const c_void) {
135        unsafe {
136            msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setGroups:), groups);
137        }
138    }
139}
140
141impl Default for LinkedFunctions {
142    fn default() -> Self {
143        Self::new().expect("failed to create LinkedFunctions")
144    }
145}
146
147impl Clone for LinkedFunctions {
148    fn clone(&self) -> Self {
149        unsafe {
150            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
151            Self::from_raw(ptr).expect("failed to copy LinkedFunctions")
152        }
153    }
154}
155
156impl Drop for LinkedFunctions {
157    fn drop(&mut self) {
158        unsafe {
159            msg_send_0::<()>(self.as_ptr(), sel!(release));
160        }
161    }
162}
163
164impl Referencing for LinkedFunctions {
165    #[inline]
166    fn as_ptr(&self) -> *const c_void {
167        self.0.as_ptr()
168    }
169}
170
171unsafe impl Send for LinkedFunctions {}
172unsafe impl Sync for LinkedFunctions {}
173
174impl std::fmt::Debug for LinkedFunctions {
175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
176        f.debug_struct("LinkedFunctions").finish()
177    }
178}