use objc2::{Message, extern_protocol, msg_send, rc::Retained, runtime::ProtocolObject};
use objc2_foundation::{NSObjectProtocol, NSString};
use crate::{
MTL4BinaryFunction, MTL4BinaryFunctionDescriptor, MTL4ComputePipelineDescriptor, MTL4PipelineDescriptor,
MTL4PipelineStageDynamicLinkingDescriptor, MTL4RenderPipelineDynamicLinkingDescriptor, MTLComputePipelineState,
MTLRenderPipelineState,
};
extern_protocol!(
pub unsafe trait MTL4Archive: NSObjectProtocol + Send + Sync {}
);
pub trait MTL4ArchiveExt: MTL4Archive + Message {
fn new_compute_pipeline_state_with_descriptor(
&self,
descriptor: &MTL4ComputePipelineDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLComputePipelineState>>, crate::MetalError>
where
Self: Sized,
{
unsafe { msg_send![self, newComputePipelineStateWithDescriptor: descriptor, error: _] }
.map_err(crate::MetalError::from_nserror)
}
fn new_compute_pipeline_state_with_descriptor_dynamic_linking_descriptor(
&self,
descriptor: &MTL4ComputePipelineDescriptor,
dynamic_linking_descriptor: &MTL4PipelineStageDynamicLinkingDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLComputePipelineState>>, crate::MetalError>
where
Self: Sized,
{
unsafe {
msg_send![
self,
newComputePipelineStateWithDescriptor: descriptor,
dynamicLinkingDescriptor: dynamic_linking_descriptor,
error: _
]
}
.map_err(crate::MetalError::from_nserror)
}
fn new_render_pipeline_state_with_descriptor(
&self,
descriptor: &MTL4PipelineDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLRenderPipelineState>>, crate::MetalError>
where
Self: Sized,
{
unsafe { msg_send![self, newRenderPipelineStateWithDescriptor: descriptor, error: _] }
.map_err(crate::MetalError::from_nserror)
}
fn new_render_pipeline_state_with_descriptor_dynamic_linking_descriptor(
&self,
descriptor: &MTL4PipelineDescriptor,
dynamic_linking_descriptor: &MTL4RenderPipelineDynamicLinkingDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLRenderPipelineState>>, crate::MetalError>
where
Self: Sized,
{
unsafe {
msg_send![
self,
newRenderPipelineStateWithDescriptor: descriptor,
dynamicLinkingDescriptor: dynamic_linking_descriptor,
error: _
]
}
.map_err(crate::MetalError::from_nserror)
}
fn new_binary_function_with_descriptor(
&self,
descriptor: &MTL4BinaryFunctionDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTL4BinaryFunction>>, crate::MetalError>
where
Self: Sized,
{
unsafe { msg_send![self, newBinaryFunctionWithDescriptor: descriptor, error: _] }
.map_err(crate::MetalError::from_nserror)
}
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()];
}
}
}
impl<T: MTL4Archive + Message> MTL4ArchiveExt for T {}
#[cfg(test)]
mod tests {
use objc2::{rc::Retained, runtime::ProtocolObject};
use super::{MTL4Archive, MTL4ArchiveExt};
use crate::{MTL4ComputePipelineDescriptor, MTLComputePipelineState, MetalError};
#[test]
fn fallible_methods_have_rust_native_signatures() {
let _: fn(
&ProtocolObject<dyn MTL4Archive>,
&MTL4ComputePipelineDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLComputePipelineState>>, MetalError> =
<ProtocolObject<dyn MTL4Archive> as MTL4ArchiveExt>::new_compute_pipeline_state_with_descriptor;
}
}