Skip to main content

mtl_gpu/mtl4/
compiler_task.rs

1//! MTL4 CompilerTask implementation.
2//!
3//! Corresponds to `Metal/MTL4CompilerTask.hpp`.
4
5use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::Referencing;
9use mtl_sys::{msg_send_0, sel};
10
11use super::enums::CompilerTaskStatus;
12
13// Forward declaration - Compiler will be defined in compiler.rs
14// We use a raw pointer here to avoid circular dependencies
15
16// ============================================================
17// CompilerTask
18// ============================================================
19
20/// A task representing an asynchronous compilation operation.
21///
22/// C++ equivalent: `MTL4::CompilerTask`
23///
24/// CompilerTask represents an in-progress compilation that can be
25/// waited on or queried for status.
26#[repr(transparent)]
27pub struct CompilerTask(NonNull<c_void>);
28
29impl CompilerTask {
30    /// Create a CompilerTask from a raw pointer.
31    #[inline]
32    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
33        NonNull::new(ptr).map(Self)
34    }
35
36    /// Get the raw pointer.
37    #[inline]
38    pub fn as_raw(&self) -> *mut c_void {
39        self.0.as_ptr()
40    }
41
42    /// Get the compiler that created this task.
43    ///
44    /// C++ equivalent: `Compiler* compiler() const`
45    ///
46    /// Returns the raw pointer to the compiler. Use `Compiler::from_raw`
47    /// to wrap it if needed.
48    pub fn compiler_raw(&self) -> *mut c_void {
49        unsafe { msg_send_0(self.as_ptr(), sel!(compiler)) }
50    }
51
52    /// Get the task status.
53    ///
54    /// C++ equivalent: `CompilerTaskStatus status() const`
55    pub fn status(&self) -> CompilerTaskStatus {
56        unsafe { msg_send_0(self.as_ptr(), sel!(status)) }
57    }
58
59    /// Wait until the task is completed.
60    ///
61    /// C++ equivalent: `void waitUntilCompleted()`
62    ///
63    /// Blocks the current thread until the compilation finishes.
64    pub fn wait_until_completed(&self) {
65        unsafe {
66            let _: () = msg_send_0(self.as_ptr(), sel!(waitUntilCompleted));
67        }
68    }
69}
70
71impl Clone for CompilerTask {
72    fn clone(&self) -> Self {
73        unsafe {
74            mtl_sys::msg_send_0::<*mut c_void>(self.as_ptr(), mtl_sys::sel!(retain));
75        }
76        Self(self.0)
77    }
78}
79
80impl Drop for CompilerTask {
81    fn drop(&mut self) {
82        unsafe {
83            mtl_sys::msg_send_0::<()>(self.as_ptr(), mtl_sys::sel!(release));
84        }
85    }
86}
87
88impl Referencing for CompilerTask {
89    #[inline]
90    fn as_ptr(&self) -> *const c_void {
91        self.0.as_ptr()
92    }
93}
94
95unsafe impl Send for CompilerTask {}
96unsafe impl Sync for CompilerTask {}
97
98impl std::fmt::Debug for CompilerTask {
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        f.debug_struct("CompilerTask")
101            .field("status", &self.status())
102            .finish()
103    }
104}
105
106#[cfg(test)]
107mod tests {
108    use super::*;
109
110    #[test]
111    fn test_compiler_task_size() {
112        assert_eq!(
113            std::mem::size_of::<CompilerTask>(),
114            std::mem::size_of::<*mut c_void>()
115        );
116    }
117}