use core::{ffi::c_void, ptr::NonNull};
use objc2::{Message, extern_protocol, msg_send, rc::Retained, runtime::ProtocolObject};
use objc2_foundation::{NSError, NSObjectProtocol, NSString};
use crate::{
MTLBuffer, MTLIOCommandBufferCompletedHandler, MTLIOFileHandle, MTLIOStatus, MTLOrigin, MTLSharedEvent, MTLSize,
MTLTexture,
};
extern_protocol!(
pub unsafe trait MTLIOCommandBuffer: NSObjectProtocol {
#[unsafe(method(loadBytes:size:sourceHandle:sourceHandleOffset:))]
#[unsafe(method_family = none)]
fn load_bytes_size_source_handle_source_handle_offset(
&self,
pointer: NonNull<c_void>,
size: usize,
source_handle: &ProtocolObject<dyn MTLIOFileHandle>,
source_handle_offset: usize,
);
#[unsafe(method(loadBuffer:offset:size:sourceHandle:sourceHandleOffset:))]
#[unsafe(method_family = none)]
fn load_buffer_offset_size_source_handle_source_handle_offset(
&self,
buffer: &ProtocolObject<dyn MTLBuffer>,
offset: usize,
size: usize,
source_handle: &ProtocolObject<dyn MTLIOFileHandle>,
source_handle_offset: usize,
);
#[unsafe(method(loadTexture:slice:level:size:sourceBytesPerRow:sourceBytesPerImage:destinationOrigin:sourceHandle:sourceHandleOffset:))]
#[unsafe(method_family = none)]
fn load_texture_slice_level_size_source_bytes_per_row_source_bytes_per_image_destination_origin_source_handle_source_handle_offset(
&self,
texture: &ProtocolObject<dyn MTLTexture>,
slice: usize,
level: usize,
size: MTLSize,
source_bytes_per_row: usize,
source_bytes_per_image: usize,
destination_origin: MTLOrigin,
source_handle: &ProtocolObject<dyn MTLIOFileHandle>,
source_handle_offset: usize,
);
#[unsafe(method(copyStatusToBuffer:offset:))]
#[unsafe(method_family = none)]
fn copy_status_to_buffer_offset(
&self,
buffer: &ProtocolObject<dyn MTLBuffer>,
offset: usize,
);
#[unsafe(method(commit))]
#[unsafe(method_family = none)]
fn commit(&self);
#[unsafe(method(waitUntilCompleted))]
#[unsafe(method_family = none)]
fn wait_until_completed(&self);
#[unsafe(method(tryCancel))]
#[unsafe(method_family = none)]
fn try_cancel(&self);
#[unsafe(method(addBarrier))]
#[unsafe(method_family = none)]
fn add_barrier(&self);
#[unsafe(method(popDebugGroup))]
#[unsafe(method_family = none)]
fn pop_debug_group(&self);
#[unsafe(method(status))]
#[unsafe(method_family = none)]
fn status(&self) -> MTLIOStatus;
#[unsafe(method(error))]
#[unsafe(method_family = none)]
fn error(&self) -> Option<Retained<NSError>>;
#[unsafe(method(enqueue))]
#[unsafe(method_family = none)]
fn enqueue(&self);
#[unsafe(method(waitForEvent:value:))]
#[unsafe(method_family = none)]
fn wait_for_event_value(
&self,
event: &ProtocolObject<dyn MTLSharedEvent>,
value: u64,
);
#[unsafe(method(signalEvent:value:))]
#[unsafe(method_family = none)]
fn signal_event_value(
&self,
event: &ProtocolObject<dyn MTLSharedEvent>,
value: u64,
);
}
);
#[allow(unused)]
pub trait MTLIOCommandBufferExt: MTLIOCommandBuffer + Message {
fn push_debug_group(
&self,
name: &str,
);
fn label(&self) -> Option<String>;
fn set_label(
&self,
label: Option<&str>,
);
fn add_completed_handler(
&self,
handler: &MTLIOCommandBufferCompletedHandler,
);
}
impl MTLIOCommandBufferExt for ProtocolObject<dyn MTLIOCommandBuffer> {
fn push_debug_group(
&self,
name: &str,
) {
unsafe {
let _: () = msg_send![self, pushDebugGroup: &*NSString::from_str(name)];
}
}
fn label(&self) -> Option<String> {
let s: Option<Retained<NSString>> = unsafe { msg_send![self, label] };
s.map(|v| v.to_string())
}
fn set_label(
&self,
label: Option<&str>,
) {
unsafe {
let _: () = msg_send![self, setLabel: label.map(NSString::from_str).as_deref()];
}
}
fn add_completed_handler(
&self,
handler: &MTLIOCommandBufferCompletedHandler,
) {
unsafe {
let _: () = msg_send![self, addCompletedHandler: &**handler];
}
}
}