mtl_gpu/mtl4/
library_descriptor.rs1use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::Referencing;
9use mtl_sys::{msg_send_0, msg_send_1, sel};
10
11use crate::CompileOptions;
12
13#[repr(transparent)]
24pub struct LibraryDescriptor(NonNull<c_void>);
25
26impl LibraryDescriptor {
27 #[inline]
29 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
30 NonNull::new(ptr).map(Self)
31 }
32
33 #[inline]
35 pub fn as_raw(&self) -> *mut c_void {
36 self.0.as_ptr()
37 }
38
39 pub fn new() -> Option<Self> {
41 unsafe {
42 let class = mtl_sys::Class::get("MTL4LibraryDescriptor")?;
43 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
44 if ptr.is_null() {
45 return None;
46 }
47 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
48 Self::from_raw(ptr)
49 }
50 }
51
52 pub fn name(&self) -> Option<String> {
56 unsafe {
57 let ns_string: *mut c_void = msg_send_0(self.as_ptr(), sel!(name));
58 if ns_string.is_null() {
59 return None;
60 }
61 let c_str: *const i8 = msg_send_0(ns_string, sel!(UTF8String));
62 if c_str.is_null() {
63 return None;
64 }
65 Some(
66 std::ffi::CStr::from_ptr(c_str)
67 .to_string_lossy()
68 .into_owned(),
69 )
70 }
71 }
72
73 pub fn set_name(&self, name: &str) {
77 if let Some(ns_name) = mtl_foundation::String::from_str(name) {
78 unsafe {
79 let _: () = msg_send_1(self.as_ptr(), sel!(setName:), ns_name.as_ptr());
80 }
81 }
82 }
83
84 pub fn source(&self) -> Option<String> {
88 unsafe {
89 let ns_string: *mut c_void = msg_send_0(self.as_ptr(), sel!(source));
90 if ns_string.is_null() {
91 return None;
92 }
93 let c_str: *const i8 = msg_send_0(ns_string, sel!(UTF8String));
94 if c_str.is_null() {
95 return None;
96 }
97 Some(
98 std::ffi::CStr::from_ptr(c_str)
99 .to_string_lossy()
100 .into_owned(),
101 )
102 }
103 }
104
105 pub fn set_source(&self, source: &str) {
109 if let Some(ns_source) = mtl_foundation::String::from_str(source) {
110 unsafe {
111 let _: () = msg_send_1(self.as_ptr(), sel!(setSource:), ns_source.as_ptr());
112 }
113 }
114 }
115
116 pub fn options(&self) -> Option<CompileOptions> {
120 unsafe {
121 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(options));
122 CompileOptions::from_raw(ptr)
123 }
124 }
125
126 pub fn set_options(&self, options: &CompileOptions) {
130 unsafe {
131 let _: () = msg_send_1(self.as_ptr(), sel!(setOptions:), options.as_ptr());
132 }
133 }
134}
135
136impl Clone for LibraryDescriptor {
137 fn clone(&self) -> Self {
138 unsafe {
139 mtl_sys::msg_send_0::<*mut c_void>(self.as_ptr(), mtl_sys::sel!(retain));
140 }
141 Self(self.0)
142 }
143}
144
145impl Drop for LibraryDescriptor {
146 fn drop(&mut self) {
147 unsafe {
148 mtl_sys::msg_send_0::<()>(self.as_ptr(), mtl_sys::sel!(release));
149 }
150 }
151}
152
153impl Referencing for LibraryDescriptor {
154 #[inline]
155 fn as_ptr(&self) -> *const c_void {
156 self.0.as_ptr()
157 }
158}
159
160unsafe impl Send for LibraryDescriptor {}
161unsafe impl Sync for LibraryDescriptor {}
162
163impl std::fmt::Debug for LibraryDescriptor {
164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165 f.debug_struct("LibraryDescriptor")
166 .field("name", &self.name())
167 .finish()
168 }
169}
170
171#[cfg(test)]
172mod tests {
173 use super::*;
174
175 #[test]
176 fn test_library_descriptor_size() {
177 assert_eq!(
178 std::mem::size_of::<LibraryDescriptor>(),
179 std::mem::size_of::<*mut c_void>()
180 );
181 }
182}