use objc2::{Message, extern_protocol, msg_send, rc::Retained, runtime::ProtocolObject};
use objc2_foundation::{NSObjectProtocol, NSString};
use crate::{MTLDataType, MTLTensorDataType, MTLTensorExtents, MTLTextureType};
extern_protocol!(
pub unsafe trait MTLBinding: NSObjectProtocol {
#[unsafe(method(type))]
#[unsafe(method_family = none)]
fn binding_type(&self) -> crate::argument::MTLBindingType;
#[unsafe(method(access))]
#[unsafe(method_family = none)]
fn access(&self) -> crate::argument::MTLBindingAccess;
#[unsafe(method(index))]
#[unsafe(method_family = none)]
fn index(&self) -> usize;
#[unsafe(method(isUsed))]
#[unsafe(method_family = none)]
fn is_used(&self) -> bool;
#[unsafe(method(isArgument))]
#[unsafe(method_family = none)]
fn is_argument(&self) -> bool;
}
);
#[allow(unused)]
pub trait MTLBindingExt: MTLBinding + Message {
fn name(&self) -> String;
}
impl MTLBindingExt for ProtocolObject<dyn MTLBinding> {
fn name(&self) -> String {
let ns: Retained<NSString> = unsafe { msg_send![self, name] };
ns.to_string()
}
}
extern_protocol!(
pub unsafe trait MTLBufferBinding: MTLBinding {
#[unsafe(method(bufferAlignment))]
#[unsafe(method_family = none)]
fn buffer_alignment(&self) -> usize;
#[unsafe(method(bufferDataSize))]
#[unsafe(method_family = none)]
fn buffer_data_size(&self) -> usize;
#[unsafe(method(bufferDataType))]
#[unsafe(method_family = none)]
fn buffer_data_type(&self) -> MTLDataType;
#[unsafe(method(bufferStructType))]
#[unsafe(method_family = none)]
fn buffer_struct_type(&self) -> Option<Retained<crate::argument::MTLStructType>>;
#[unsafe(method(bufferPointerType))]
#[unsafe(method_family = none)]
fn buffer_pointer_type(&self) -> Option<Retained<crate::argument::MTLPointerType>>;
}
);
extern_protocol!(
pub unsafe trait MTLThreadgroupBinding: MTLBinding {
#[unsafe(method(threadgroupMemoryAlignment))]
#[unsafe(method_family = none)]
fn threadgroup_memory_alignment(&self) -> usize;
#[unsafe(method(threadgroupMemoryDataSize))]
#[unsafe(method_family = none)]
fn threadgroup_memory_data_size(&self) -> usize;
}
);
extern_protocol!(
pub unsafe trait MTLTextureBinding: MTLBinding {
#[unsafe(method(textureType))]
#[unsafe(method_family = none)]
fn texture_type(&self) -> MTLTextureType;
#[unsafe(method(textureDataType))]
#[unsafe(method_family = none)]
fn texture_data_type(&self) -> MTLDataType;
#[unsafe(method(isDepthTexture))]
#[unsafe(method_family = none)]
fn is_depth_texture(&self) -> bool;
#[unsafe(method(arrayLength))]
#[unsafe(method_family = none)]
fn array_length(&self) -> usize;
}
);
extern_protocol!(
pub unsafe trait MTLObjectPayloadBinding: MTLBinding {
#[unsafe(method(objectPayloadAlignment))]
#[unsafe(method_family = none)]
fn object_payload_alignment(&self) -> usize;
#[unsafe(method(objectPayloadDataSize))]
#[unsafe(method_family = none)]
fn object_payload_data_size(&self) -> usize;
}
);
extern_protocol!(
pub unsafe trait MTLTensorBinding: MTLBinding {
#[unsafe(method(tensorDataType))]
#[unsafe(method_family = none)]
fn tensor_data_type(&self) -> MTLTensorDataType;
#[unsafe(method(indexType))]
#[unsafe(method_family = none)]
fn index_type(&self) -> MTLDataType;
#[unsafe(method(dimensions))]
#[unsafe(method_family = none)]
fn dimensions(&self) -> Option<Retained<MTLTensorExtents>>;
}
);