iron_oxide/lib.rs
1//! `iron-oxide` provides unsafe [Metal](https://developer.apple.com/documentation/metal?language=objc)
2//! bindings for Rust.
3//!
4//! The Metal documentation for most structs, traits, methods, and functions can be found by
5//! googling their names (adjusted from snake_case to camelCase).
6//!
7//! Not all of Metal's functionality is added. The pointer underlying a MTL(something) can
8//! be accessed with `get_ptr`, and messages can be sent to it with `objc`'s `msg_send!`, if
9//! necessary functionality isn't yet implemented. This is very unsafe.
10//!
11//! It is the responsibility of the user to not use methods or functions which do not exist in
12//! OS versions below what they support.
13//!
14//! See the examples directory for examples.
15//!
16//! This crate is licensed under the MIT license.
17
18use objc::Message;
19use std::ops::Deref;
20
21mod commandbuffer;
22mod commandqueue;
23mod depthstencil;
24mod device;
25mod drawable;
26mod encoder;
27mod layer;
28mod library;
29mod misc;
30mod pipeline;
31mod resource;
32mod sampler;
33pub use commandbuffer::*;
34pub use commandqueue::*;
35pub use depthstencil::*;
36pub use device::*;
37pub use drawable::*;
38pub use encoder::*;
39pub use layer::*;
40pub use library::*;
41pub use misc::*;
42pub use pipeline::*;
43pub use resource::*;
44pub use sampler::*;
45
46/// Reexports important macros for sending messages from the `objc` crate:
47/// - `msg_send`
48/// - `class`
49/// - `sel`
50/// - `sel_impl`
51pub mod import_objc_macros {
52 pub use objc::{class, msg_send, sel, sel_impl};
53}
54
55type ObjectPointerMarker = objc::runtime::Object;
56
57#[derive(Copy, Clone)]
58#[repr(C)]
59/// A messageable pointer to a (presumed) Objective C object.
60pub struct ObjectPointer(*mut ObjectPointerMarker);
61impl Deref for ObjectPointer {
62 type Target = ObjectPointerMarker;
63
64 fn deref(&self) -> &Self::Target {
65 unsafe { &*self.0 }
66 }
67}
68unsafe impl Message for ObjectPointer {}
69
70pub trait Array<T: Object>: Object {
71 /// Puts in the array at the specified index the specified object.
72 unsafe fn set_object_at_indexed_subscript(&self, index: NSUInteger, obj: &T) {
73 use crate::import_objc_macros::*;
74 msg_send![self.get_ptr(), setObject:obj.get_ptr() atIndexedSubscript:index]
75 }
76}
77
78/// Represents an Objective C object.
79///
80/// # Requirements
81///
82/// There *must* be for an implementation of Object an implementation of Drop using
83/// the `handle!` macro. See `handle!` for more information and an example.
84pub trait Object: Drop {
85 /// Constructs an object from the provided pointer.
86 ///
87 /// The pointer provided *must* be a valid pointer to an Objective C object which can
88 /// accept the messages which the used implementation of Object will send.
89 unsafe fn from_ptr(ptr: ObjectPointer) -> Self
90 where
91 Self: Sized;
92 /// Returns the underlying pointer of the object.
93 ///
94 /// The returned pointer *must* be a valid pointer to an Objective C object.
95 fn get_ptr(&self) -> ObjectPointer;
96}
97
98/// Aliased exclusively so that, should the watchOS target be added to Rust, NSInteger can
99/// conform to watchOS' 32-bit architecture.
100pub type NSInteger = i64;
101/// Aliased exclusively so that, should the watchOS target be added to Rust, NSUInteger can
102/// conform to watchOS' 32-bit architecture.
103pub type NSUInteger = u64;
104/// Aliased exclusively so that, should the watchOS target be added to Rust, CGFloat can
105/// conform to watchOS' 32-bit architecture.
106pub type CGFloat = f64;
107
108#[macro_export]
109/// Provides an implementation of `Drop` which implements lifetime-based releasing
110/// on the implemented type's pointer to an Objective C object.
111///
112/// This implementation of `Drop` decrements the reference count of the object which the
113/// `get_ptr` method returns. This ensures that the object to which the implementor points
114/// lives only for the lifetime of the implementor.
115///
116/// # Requirements
117///
118/// The ident passed into `handle!` must be the correct local name of a struct or enum which
119/// implements `Object`.
120///
121/// # Example
122///
123/// ```
124/// use iron_oxide::{ObjectPointer, handle, Object};
125///
126/// struct Wrapper(ObjectPointer);
127/// handle!(Wrapper);
128///
129/// impl Object for Wrapper {
130/// unsafe fn from_ptr(ptr: ObjectPointer) -> Self where
131/// Self: Sized {
132/// Wrapper(ptr)
133/// }
134///
135/// fn get_ptr(&self) -> ObjectPointer {
136/// self.0
137/// }
138///
139/// }
140/// ```
141macro_rules! handle {
142 ($name:ident) => {
143 impl Drop for $name {
144 fn drop(&mut self) {
145 use crate::import_objc_macros::*;
146 unsafe {
147 let _: () = msg_send![self.get_ptr(), release];
148 }
149 }
150 }
151 };
152}