iron_oxide/
misc.rs

1use crate::import_objc_macros::*;
2use crate::{handle, CGFloat, NSInteger, NSUInteger, Object, ObjectPointer};
3use std::fmt::{Debug, Display, Formatter};
4
5/// Takes an implementor of `Object` and logs its description and retain count.
6///
7/// Requires an active logger.
8///
9/// Assumes that the implementation of `get_ptr` given by `T` unconditionally
10/// returns a pointer to a valid Objective-C object inheriting from `NSObject`.
11///
12/// # Example
13///
14/// ```
15/// fn main() {
16///     use iron_oxide::{MTLCreateSystemDefaultDevice, debug};
17///
18///     let device = unsafe { MTLCreateSystemDefaultDevice() };
19///     unsafe { debug(&device) };
20/// }
21/// ```
22pub unsafe fn debug<T: Object>(obj: &T) {
23    use crate::import_objc_macros::*;
24
25    let count: NSUInteger = msg_send![obj.get_ptr(), retainCount];
26    let description = ObjectPointer(msg_send![obj.get_ptr(), description]);
27    let description = {
28        let bytes: *const u8 = msg_send![description, UTF8String];
29        let len: NSUInteger = msg_send![description, length];
30        let bytes = std::slice::from_raw_parts(bytes, len as usize);
31        std::str::from_utf8(bytes).unwrap()
32    };
33
34    log::log!(log::Level::Info, "{}", description);
35    log::log!(log::Level::Info, "Retain count of {}", count);
36}
37
38#[repr(u64)]
39pub enum MTLCompareFunction {
40    Never = 0,
41    Less = 1,
42    Equal = 2,
43    LessEqual = 3,
44    Greater = 4,
45    NotEqual = 5,
46    GreaterEqual = 6,
47    Always = 7,
48}
49
50#[allow(non_camel_case_types)]
51#[repr(u64)]
52pub enum MTLPixelFormat {
53    Invalid = 0,
54    A8Unorm = 1,
55    R8Unorm = 10,
56    R8Unorm_sRGB = 11,
57    R8Snorm = 12,
58    R8Uint = 13,
59    R8Sint = 14,
60    R16Unorm = 20,
61    R16Snorm = 22,
62    R16Uint = 23,
63    R16Sint = 24,
64    R16Float = 25,
65    RG8Unorm = 30,
66    RG8Unorm_sRGB = 31,
67    RG8Snorm = 32,
68    RG8Uint = 33,
69    RG8Sint = 34,
70    B5G6R5Unorm = 40,
71    A1BGR5Unorm = 41,
72    ABGR4Unorm = 42,
73    BGR5A1Unorm = 43,
74    R32Uint = 53,
75    R32Sint = 54,
76    R32Float = 55,
77    RG16Unorm = 60,
78    RG16Snorm = 62,
79    RG16Uint = 63,
80    RG16Sint = 64,
81    RG16Float = 65,
82    RGBA8Unorm = 70,
83    RGBA8Unorm_sRGB = 71,
84    RGBA8Snorm = 72,
85    RGBA8Uint = 73,
86    RGBA8Sint = 74,
87    BGRA8Unorm = 80,
88    BGRA8Unorm_sRGB = 81,
89    RGB10A2Unorm = 90,
90    RGB10A2Uint = 91,
91    RG11B10Float = 92,
92    RGB9E5Float = 93,
93    BGR10A2Unorm = 94,
94    RG32Uint = 103,
95    RG32Sint = 104,
96    RG32Float = 105,
97    RGBA16Unorm = 110,
98    RGBA16Snorm = 112,
99    RGBA16Uint = 113,
100    RGBA16Sint = 114,
101    RGBA16Float = 115,
102    RGBA32Uint = 123,
103    RGBA32Sint = 124,
104    RGBA32Float = 125,
105    BC1_RGBA = 130,
106    BC1_RGBA_sRGB = 131,
107    BC2_RGBA = 132,
108    BC2_RGBA_sRGB = 133,
109    BC3_RGBA = 134,
110    BC3_RGBA_sRGB = 135,
111    BC4_RUnorm = 140,
112    BC4_RSnorm = 141,
113    BC5_RGUnorm = 142,
114    BC5_RGSnorm = 143,
115    BC6H_RGBFloat = 150,
116    BC6H_RGBUfloat = 151,
117    BC7_RGBAUnorm = 152,
118    BC7_RGBAUnorm_sRGB = 153,
119    PVRTC_RGB_2BPP = 160,
120    PVRTC_RGB_2BPP_sRGB = 161,
121    PVRTC_RGB_4BPP = 162,
122    PVRTC_RGB_4BPP_sRGB = 163,
123    PVRTC_RGBA_2BPP = 164,
124    PVRTC_RGBA_2BPP_sRGB = 165,
125    PVRTC_RGBA_4BPP = 166,
126    PVRTC_RGBA_4BPP_sRGB = 167,
127    EAC_R11Unorm = 170,
128    EAC_R11Snorm = 172,
129    EAC_RG11Unorm = 174,
130    EAC_RG11Snorm = 176,
131    EAC_RGBA8 = 178,
132    EAC_RGBA8_sRGB = 179,
133    ETC2_RGB8 = 180,
134    ETC2_RGB8_sRGB = 181,
135    ETC2_RGB8A1 = 182,
136    ETC2_RGB8A1_sRGB = 183,
137    ASTC_4x4_sRGB = 186,
138    ASTC_5x4_sRGB = 187,
139    ASTC_5x5_sRGB = 188,
140    ASTC_6x5_sRGB = 189,
141    ASTC_6x6_sRGB = 190,
142    ASTC_8x5_sRGB = 192,
143    ASTC_8x6_sRGB = 193,
144    ASTC_8x8_sRGB = 194,
145    ASTC_10x5_sRGB = 195,
146    ASTC_10x6_sRGB = 196,
147    ASTC_10x8_sRGB = 197,
148    ASTC_10x10_sRGB = 198,
149    ASTC_12x10_sRGB = 199,
150    ASTC_12x12_sRGB = 200,
151    ASTC_4x4_LDR = 204,
152    ASTC_5x4_LDR = 205,
153    ASTC_5x5_LDR = 206,
154    ASTC_6x5_LDR = 207,
155    ASTC_6x6_LDR = 208,
156    ASTC_8x5_LDR = 210,
157    ASTC_8x6_LDR = 211,
158    ASTC_8x8_LDR = 212,
159    ASTC_10x5_LDR = 213,
160    ASTC_10x6_LDR = 214,
161    ASTC_10x8_LDR = 215,
162    ASTC_10x10_LDR = 216,
163    ASTC_12x10_LDR = 217,
164    ASTC_12x12_LDR = 218,
165    GBGR422 = 240,
166    BGRG422 = 241,
167    Depth16Unorm = 250,
168    Depth32Float = 252,
169    Stencil8 = 253,
170    Depth24Unorm_Stencil8 = 255,
171    Depth32Float_Stencil8 = 260,
172    X32_Stencil8 = 261,
173    X24_Stencil8 = 262,
174    BGRA10_XR = 552,
175    BGRA10_XR_SRGB = 553,
176    BGR10_XR = 554,
177    BGR10_XR_SRGB = 555,
178}
179
180pub struct NSError(ObjectPointer);
181handle!(NSError);
182
183impl NSError {
184    pub unsafe fn get_code(&self) -> NSInteger {
185        msg_send![self.get_ptr(), code]
186    }
187    pub unsafe fn get_domain(&self) -> &str {
188        let domain = ObjectPointer(msg_send![self.get_ptr(), domain]);
189        let bytes: *const u8 = msg_send![domain, UTF8String];
190        let len: NSUInteger = msg_send![domain, length];
191        let bytes = std::slice::from_raw_parts(bytes, len as usize);
192        std::str::from_utf8(bytes).unwrap()
193    }
194    pub unsafe fn get_localized_description(&self) -> &str {
195        let desc = ObjectPointer(msg_send![self.get_ptr(), localizedDescription]);
196        let bytes: *const u8 = msg_send![desc, UTF8String];
197        let len: NSUInteger = msg_send![desc, length];
198        let bytes = std::slice::from_raw_parts(bytes, len as usize);
199        std::str::from_utf8(bytes).unwrap()
200    }
201    pub unsafe fn get_localized_failure_reason(&self) -> &str {
202        let reason = ObjectPointer(msg_send![self.get_ptr(), localizedFailureReason]);
203        let bytes: *const u8 = msg_send![reason, UTF8String];
204        let len: NSUInteger = msg_send![reason, length];
205        let bytes = std::slice::from_raw_parts(bytes, len as usize);
206        std::str::from_utf8(bytes).unwrap()
207    }
208}
209
210impl Debug for NSError {
211    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
212        f.write_str(unsafe {
213            let desc = self.get_localized_description();
214            let reason = self.get_localized_failure_reason();
215            let domain = self.get_domain();
216            let code = self.get_code();
217
218            format!(
219                "\n{}Reason:\n{}\nDomain: {}\nCode: {}",
220                desc, reason, domain, code
221            )
222            .as_str()
223        })
224    }
225}
226
227impl Object for NSError {
228    unsafe fn from_ptr(ptr: ObjectPointer) -> Self
229    where
230        Self: Sized,
231    {
232        NSError(ptr)
233    }
234
235    fn get_ptr(&self) -> ObjectPointer {
236        self.0
237    }
238}
239
240/// A Rust range of NSUIntegers.
241pub type NSUIntegerRange = std::ops::Range<NSUInteger>;
242
243#[repr(C)]
244pub struct MTLRegion {
245    pub origin: MTLSize,
246    pub size: MTLSize,
247}
248
249#[repr(C)]
250pub struct NSRange {
251    pub location: NSUInteger,
252    pub length: NSUInteger,
253}
254
255#[repr(C)]
256pub struct MTLSize {
257    pub width: NSUInteger,
258    pub height: NSUInteger,
259    pub depth: NSUInteger,
260}
261
262#[repr(C)]
263pub struct CGSize {
264    pub width: CGFloat,
265    pub height: CGFloat,
266}
267
268impl Display for MTLSize {
269    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
270        f.write_str(format!("W: {}, H: {}, D: {}", self.width, self.height, self.depth).as_str())
271    }
272}
273
274#[repr(C)]
275pub struct MTLSamplePosition {
276    pub x: f32,
277    pub y: f32,
278}
279
280impl Display for MTLSamplePosition {
281    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
282        f.write_str(format!("X: {}, Y: {}", self.x, self.y).as_str())
283    }
284}