mtl_gpu/library/
vertex_attribute.rs1use std::ffi::c_void;
4use std::ptr::NonNull;
5
6use mtl_foundation::{Referencing, UInteger};
7use mtl_sys::{msg_send_0, sel};
8
9use crate::enums::DataType;
10
11#[repr(transparent)]
17pub struct VertexAttribute(pub(crate) NonNull<c_void>);
18
19impl VertexAttribute {
20 pub fn alloc() -> Option<Self> {
24 unsafe {
25 let cls = mtl_sys::Class::get("MTLVertexAttribute")?;
26 let ptr: *mut c_void = msg_send_0(cls.as_ptr(), sel!(alloc));
27 Self::from_raw(ptr)
28 }
29 }
30
31 pub fn init(&self) -> Option<Self> {
35 unsafe {
36 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(init));
37 Self::from_raw(ptr)
38 }
39 }
40
41 pub fn new() -> Option<Self> {
43 Self::alloc()?.init()
44 }
45
46 #[inline]
52 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
53 NonNull::new(ptr).map(Self)
54 }
55
56 #[inline]
58 pub fn as_raw(&self) -> *mut c_void {
59 self.0.as_ptr()
60 }
61
62 pub fn name(&self) -> Option<String> {
66 unsafe {
67 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(name));
68 if ptr.is_null() {
69 return None;
70 }
71 let utf8_ptr: *const std::ffi::c_char =
72 mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
73 if utf8_ptr.is_null() {
74 return None;
75 }
76 let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
77 Some(c_str.to_string_lossy().into_owned())
78 }
79 }
80
81 #[inline]
85 pub fn attribute_index(&self) -> UInteger {
86 unsafe { msg_send_0(self.as_ptr(), sel!(attributeIndex)) }
87 }
88
89 #[inline]
93 pub fn attribute_type(&self) -> DataType {
94 unsafe { msg_send_0(self.as_ptr(), sel!(attributeType)) }
95 }
96
97 #[inline]
101 pub fn is_active(&self) -> bool {
102 unsafe { msg_send_0(self.as_ptr(), sel!(isActive)) }
103 }
104
105 #[inline]
109 pub fn is_patch_data(&self) -> bool {
110 unsafe { msg_send_0(self.as_ptr(), sel!(isPatchData)) }
111 }
112
113 #[inline]
117 pub fn is_patch_control_point_data(&self) -> bool {
118 unsafe { msg_send_0(self.as_ptr(), sel!(isPatchControlPointData)) }
119 }
120}
121
122impl Clone for VertexAttribute {
123 fn clone(&self) -> Self {
124 unsafe {
125 msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
126 }
127 Self(self.0)
128 }
129}
130
131impl Drop for VertexAttribute {
132 fn drop(&mut self) {
133 unsafe {
134 msg_send_0::<()>(self.as_ptr(), sel!(release));
135 }
136 }
137}
138
139impl Referencing for VertexAttribute {
140 #[inline]
141 fn as_ptr(&self) -> *const c_void {
142 self.0.as_ptr()
143 }
144}
145
146unsafe impl Send for VertexAttribute {}
147unsafe impl Sync for VertexAttribute {}
148
149impl std::fmt::Debug for VertexAttribute {
150 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151 f.debug_struct("VertexAttribute")
152 .field("name", &self.name())
153 .field("attribute_index", &self.attribute_index())
154 .field("attribute_type", &self.attribute_type())
155 .field("is_active", &self.is_active())
156 .finish()
157 }
158}