Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  library.rs   Sprache: unbekannt

 
// Copyright 2017 GFX developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use super::*;

use objc::runtime::{BOOL, NO, YES};

use std::ffi::CStr;
use std::os::raw::c_char;
use std::ptr;

/// Only available on (macos(10.12), ios(10.0)
///
/// See <https://developer.apple.com/documentation/metal/mtlpatchtype/>
#[repr(u64)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum MTLPatchType {
    None = 0,
    Triangle = 1,
    Quad = 2,
}

/// See <https://developer.apple.com/documentation/metal/mtlvertexattribute/>
pub enum MTLVertexAttribute {}

foreign_obj_type! {
    type CType = MTLVertexAttribute;
    pub struct VertexAttribute;
}

impl VertexAttributeRef {
    pub fn name(&self) -> &str {
        unsafe {
            let name = msg_send![self, name];
            crate::nsstring_as_str(name)
        }
    }

    pub fn attribute_index(&self) -> u64 {
        unsafe { msg_send![self, attributeIndex] }
    }

    pub fn attribute_type(&self) -> MTLDataType {
        unsafe { msg_send![self, attributeType] }
    }

    pub fn is_active(&self) -> bool {
        unsafe { msg_send_bool![self, isActive] }
    }

    /// Only available on (macos(10.12), ios(10.0)
    pub fn is_patch_data(&self) -> bool {
        unsafe { msg_send_bool![self, isPatchData] }
    }

    /// Only available on (macos(10.12), ios(10.0)
    pub fn is_patch_control_point_data(&self) -> bool {
        unsafe { msg_send_bool![self, isPatchControlPointData] }
    }
}

/// Only available on (macos(10.12), ios(10.0))
///
/// See <https://developer.apple.com/documentation/metal/mtlattribute/>
pub enum MTLAttribute {}

foreign_obj_type! {
    type CType = MTLAttribute;
    pub struct Attribute;
}

impl AttributeRef {
    pub fn name(&self) -> &str {
        unsafe {
            let name = msg_send![self, name];
            crate::nsstring_as_str(name)
        }
    }

    pub fn attribute_index(&self) -> u64 {
        unsafe { msg_send![self, attributeIndex] }
    }

    pub fn attribute_type(&self) -> MTLDataType {
        unsafe { msg_send![self, attributeType] }
    }

    pub fn is_active(&self) -> bool {
        unsafe { msg_send_bool![self, isActive] }
    }

    /// Only available on (macos(10.12), ios(10.0))
    pub fn is_patch_data(&self) -> bool {
        unsafe { msg_send_bool![self, isPatchData] }
    }

    /// Only available on (macos(10.12), ios(10.0))
    pub fn is_patch_control_point_data(&self) -> bool {
        unsafe { msg_send_bool![self, isPatchControlPointData] }
    }
}

/// See <https://developer.apple.com/documentation/metal/mtlfunctiontype/>
#[repr(u64)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum MTLFunctionType {
    Vertex = 1,
    Fragment = 2,
    Kernel = 3,
    /// Only available on (macos(11.0), ios(14.0))
    Visible = 5,
    /// Only available on (macos(11.0), ios(14.0))
    Intersection = 6,
}

/// Only available on (macos(10.12), ios(10.0))
///
/// See <https://developer.apple.com/documentation/metal/mtlfunctionconstant/>
pub enum MTLFunctionConstant {}

foreign_obj_type! {
    type CType = MTLFunctionConstant;
    pub struct FunctionConstant;
}

impl FunctionConstantRef {
    pub fn name(&self) -> &str {
        unsafe {
            let name = msg_send![self, name];
            crate::nsstring_as_str(name)
        }
    }

    pub fn data_type(&self) -> MTLDataType {
        unsafe { msg_send![self, type] }
    }

    pub fn index(&self) -> NSUInteger {
        unsafe { msg_send![self, index] }
    }

    pub fn required(&self) -> bool {
        unsafe { msg_send_bool![self, required] }
    }
}

bitflags::bitflags! {
    /// Only available on (macos(11.0), ios(14.0))
    ///
    /// See <https://developer.apple.com/documentation/metal/mtlfunctionoptions/>
    #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
    pub struct MTLFunctionOptions: NSUInteger {
        const None = 0;
        const CompileToBinary = 1 << 0;
    }
}

/// Only available on (macos(11.0), ios(14.0))
///
/// See <https://developer.apple.com/documentation/metal/mtlfunctiondescriptor/>
pub enum MTLFunctionDescriptor {}

foreign_obj_type! {
    type CType = MTLFunctionDescriptor;
    pub struct FunctionDescriptor;
}

impl FunctionDescriptor {
    pub fn new() -> Self {
        unsafe {
            let class = class!(MTLFunctionDescriptor);
            msg_send![class, new]
        }
    }
}

impl FunctionDescriptorRef {
    pub fn name(&self) -> &str {
        unsafe {
            let name = msg_send![self, name];
            crate::nsstring_as_str(name)
        }
    }

    pub fn set_name(&self, name: &str) {
        unsafe {
            let ns_name = crate::nsstring_from_str(name);
            let () = msg_send![self, setName: ns_name];
        }
    }

    pub fn specialized_name(&self) -> &str {
        unsafe {
            let name = msg_send![self, specializedName];
            crate::nsstring_as_str(name)
        }
    }

    pub fn set_specialized_name(&self, name: &str) {
        unsafe {
            let ns_name = crate::nsstring_from_str(name);
            let () = msg_send![self, setSpecializedName: ns_name];
        }
    }

    pub fn constant_values(&self) -> &FunctionConstantValuesRef {
        unsafe { msg_send![self, constantValues] }
    }

    pub fn set_constant_values(&self, values: &FunctionConstantValuesRef) {
        unsafe { msg_send![self, setConstantValues: values] }
    }

    pub fn options(&self) -> MTLFunctionOptions {
        unsafe { msg_send![self, options] }
    }

    pub fn set_options(&self, options: MTLFunctionOptions) {
        unsafe { msg_send![self, setOptions: options] }
    }
}

/// Only available on (macos(11.0), ios(14.0))
///
/// See <https://developer.apple.com/documentation/metal/mtlintersectionfunctiondescriptor/>
pub enum MTLIntersectionFunctionDescriptor {}

foreign_obj_type! {
    type CType = MTLIntersectionFunctionDescriptor;
    pub struct IntersectionFunctionDescriptor;
    type ParentType = FunctionDescriptor;
}

/// Only available on (macos(11.0), ios(14.0))
///
/// See <https://developer.apple.com/documentation/metal/mtlfunctionhandle/>
pub enum MTLFunctionHandle {}

foreign_obj_type! {
    type CType = MTLFunctionHandle;
    pub struct FunctionHandle;
}

impl FunctionHandleRef {
    pub fn device(&self) -> &DeviceRef {
        unsafe { msg_send![self, device] }
    }

    pub fn name(&self) -> &str {
        unsafe {
            let ns_name = msg_send![self, name];
            crate::nsstring_as_str(ns_name)
        }
    }

    pub fn function_type(&self) -> MTLFunctionType {
        unsafe { msg_send![self, functionType] }
    }
}

// TODO:
// MTLIntersectionFunctionSignature
// MTLIntersectionFunctionTableDescriptor
// MTLIntersectionFunctionTable

/// See <https://developer.apple.com/documentation/metal/mtlfunction/>
pub enum MTLFunction {}

foreign_obj_type! {
    type CType = MTLFunction;
    pub struct Function;
}

impl FunctionRef {
    pub fn device(&self) -> &DeviceRef {
        unsafe { msg_send![self, device] }
    }

    /// Only available on (macos(10.12), ios(10.0))
    pub fn label(&self) -> &str {
        unsafe {
            let ns_label = msg_send![self, label];
            crate::nsstring_as_str(ns_label)
        }
    }

    /// Only available on (macos(10.12), ios(10.0))
    pub fn set_label(&self, label: &str) {
        unsafe {
            let ns_label = crate::nsstring_from_str(label);
            let () = msg_send![self, setLabel: ns_label];
        }
    }

    pub fn name(&self) -> &str {
        unsafe {
            let name = msg_send![self, name];
            crate::nsstring_as_str(name)
        }
    }

    pub fn function_type(&self) -> MTLFunctionType {
        unsafe { msg_send![self, functionType] }
    }

    /// Only available on (macos(10.12), ios(10.0))
    pub fn patch_type(&self) -> MTLPatchType {
        unsafe { msg_send![self, patchType] }
    }

    /// Only available on (macos(10.12), ios(10.0))
    pub fn patch_control_point_count(&self) -> NSUInteger {
        unsafe { msg_send![self, patchControlPointCount] }
    }

    /// Only available on (macos(10.12), ios(10.0))
    pub fn vertex_attributes(&self) -> &Array<VertexAttribute> {
        unsafe { msg_send![self, vertexAttributes] }
    }

    /// Only available on (macos(10.12), ios(10.0))
    pub fn stage_input_attributes(&self) -> &Array<Attribute> {
        unsafe { msg_send![self, stageInputAttributes] }
    }

    pub fn new_argument_encoder(&self, buffer_index: NSUInteger) -> ArgumentEncoder {
        unsafe {
            let ptr = msg_send![self, newArgumentEncoderWithBufferIndex: buffer_index];
            ArgumentEncoder::from_ptr(ptr)
        }
    }

    pub fn function_constants_dictionary(&self) -> *mut Object {
        unsafe { msg_send![self, functionConstantsDictionary] }
    }

    /// Only available on (macos(11.0), ios(14.0))
    pub fn options(&self) -> MTLFunctionOptions {
        unsafe { msg_send![self, options] }
    }
}

/// See <https://developer.apple.com/documentation/metal/mtllanguageversion/>
#[repr(u64)]
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum MTLLanguageVersion {
    V1_0 = 0x10000,
    V1_1 = 0x10001,
    V1_2 = 0x10002,
    V2_0 = 0x20000,
    V2_1 = 0x20001,
    V2_2 = 0x20002,
    /// available on macOS 11.0+, iOS 14.0+
    V2_3 = 0x20003,
    /// available on macOS 12.0+, iOS 15.0+
    V2_4 = 0x20004,
    /// available on macOS 13.0+, iOS 16.0+
    V3_0 = 0x30000,
    /// available on macOS 14.0+, iOS 17.0+
    V3_1 = 0x30001,
}

/// See <https://developer.apple.com/documentation/metal/mtlfunctionconstantvalues/>
pub enum MTLFunctionConstantValues {}

foreign_obj_type! {
    type CType = MTLFunctionConstantValues;
    pub struct FunctionConstantValues;
}

impl FunctionConstantValues {
    pub fn new() -> Self {
        unsafe {
            let class = class!(MTLFunctionConstantValues);
            msg_send![class, new]
        }
    }
}

impl FunctionConstantValuesRef {
    pub fn set_constant_value_at_index(
        &self,
        value: *const c_void,
        ty: MTLDataType,
        index: NSUInteger,
    ) {
        unsafe { msg_send![self, setConstantValue:value type:ty atIndex:index] }
    }

    pub fn set_constant_values_with_range(
        &self,
        values: *const c_void,
        ty: MTLDataType,
        range: NSRange,
    ) {
        unsafe { msg_send![self, setConstantValues:values type:ty withRange:range] }
    }

    pub fn set_constant_value_with_name(&self, value: *const c_void, ty: MTLDataType, name: &str)&nbsp;{
        unsafe {
            let ns_name = crate::nsstring_from_str(name);
            msg_send![self, setConstantValue:value type:ty withName:ns_name]
        }
    }
}

/// Only available on (macos(11.0), ios(14.0))
///
/// See <https://developer.apple.com/documentation/metal/mtllibrarytype/>
#[repr(u64)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum MTLLibraryType {
    Executable = 0,
    Dynamic = 1,
}

/// See <https://developer.apple.com/documentation/metal/mtlcompileoptions/>
pub enum MTLCompileOptions {}

foreign_obj_type! {
    type CType = MTLCompileOptions;
    pub struct CompileOptions;
}

impl CompileOptions {
    pub fn new() -> Self {
        unsafe {
            let class = class!(MTLCompileOptions);
            msg_send![class, new]
        }
    }
}

impl CompileOptionsRef {
    pub unsafe fn preprocessor_macros(&self) -> *mut Object {
        msg_send![self, preprocessorMacros]
    }

    pub unsafe fn set_preprocessor_macros(&self, defines: *mut Object) {
        msg_send![self, setPreprocessorMacros: defines]
    }

    pub fn is_fast_math_enabled(&self) -> bool {
        unsafe { msg_send_bool![self, fastMathEnabled] }
    }

    pub fn set_fast_math_enabled(&self, enabled: bool) {
        unsafe { msg_send![self, setFastMathEnabled: enabled] }
    }

    /// Only available on (macos(10.11), ios(9.0))
    pub fn language_version(&self) -> MTLLanguageVersion {
        unsafe { msg_send![self, languageVersion] }
    }

    /// Only available on (macos(10.11), ios(9.0))
    pub fn set_language_version(&self, version: MTLLanguageVersion) {
        unsafe { msg_send![self, setLanguageVersion: version] }
    }

    /// Only available on (macos(11.0), ios(14.0))
    pub fn library_type(&self) -> MTLLibraryType {
        unsafe { msg_send![self, libraryType] }
    }

    /// Only available on (macos(11.0), ios(14.0))
    pub fn set_library_type(&self, lib_type: MTLLibraryType) {
        unsafe { msg_send![self, setLibraryType: lib_type] }
    }

    /// Only available on (macos(11.0), ios(14.0))
    pub fn install_name(&self) -> &str {
        unsafe {
            let name = msg_send![self, installName];
            crate::nsstring_as_str(name)
        }
    }

    /// Only available on (macos(11.0), ios(14.0))
    pub fn set_install_name(&self, name: &str) {
        unsafe {
            let install_name = crate::nsstring_from_str(name);
            let () = msg_send![self, setInstallName: install_name];
        }
    }

    /// Only available on (macos(11.0), ios(14.0))
    ///
    /// Marshal to Rust Vec
    pub fn libraries(&self) -> Vec<DynamicLibrary> {
        unsafe {
            let libraries: *mut Object = msg_send![self, libraries];
            let count: NSUInteger = msg_send![libraries, count];
            let ret = (0..count)
                .map(|i| {
                    let lib = msg_send![libraries, objectAtIndex: i];
                    DynamicLibrary::from_ptr(lib)
                })
                .collect();
            ret
        }
    }

    /// Only available on (macos(11.0), ios(14.0))
    ///
    /// As raw NSArray
    pub fn libraries_as_nsarray(&self) -> &ArrayRef<DynamicLibrary> {
        unsafe { msg_send![self, libraries] }
    }

    /// Only available on (macos(11.0), ios(14.0))
    ///
    /// Marshal from Rust slice
    pub fn set_libraries(&self, libraries: &[&DynamicLibraryRef]) {
        let ns_array = Array::<DynamicLibrary>::from_slice(libraries);
        unsafe { msg_send![self, setLibraries: ns_array] }
    }

    /// Only available on (macos(11.0), ios(14.0))
    ///
    /// From raw NSArray
    pub fn set_libraries_nsarray(&self, libraries: &ArrayRef<DynamicLibrary>) {
        unsafe { msg_send![self, setLibraries: libraries] }
    }

    /// Only available on (macos(11.0), macCatalyst(14.0), ios(13.0))
    pub fn preserve_invariance(&self) -> bool {
        unsafe { msg_send_bool![self, preserveInvariance] }
    }

    /// Only available on (macos(11.0), macCatalyst(14.0), ios(13.0))
    pub fn set_preserve_invariance(&self, preserve: bool) {
        unsafe { msg_send![self, setPreserveInvariance: preserve] }
    }
}

/// See <https://developer.apple.com/documentation/metal/mtllibraryerror/>
#[repr(u64)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum MTLLibraryError {
    Unsupported = 1,
    Internal = 2,
    CompileFailure = 3,
    CompileWarning = 4,
    /// Only available on (macos(10.12), ios(10.0))
    FunctionNotFound = 5,
    /// Only available on (macos(10.12), ios(10.0))
    FileNotFound = 6,
}

/// See <https://developer.apple.com/documentation/metal/mtllibrary/>
pub enum MTLLibrary {}

foreign_obj_type! {
    type CType = MTLLibrary;
    pub struct Library;
}

impl LibraryRef {
    pub fn device(&self) -> &DeviceRef {
        unsafe { msg_send![self, device] }
    }

    pub fn label(&self) -> &str {
        unsafe {
            let label = msg_send![self, label];
            crate::nsstring_as_str(label)
        }
    }

    pub fn set_label(&self, label: &str) {
        unsafe {
            let nslabel = crate::nsstring_from_str(label);
            let () = msg_send![self, setLabel: nslabel];
        }
    }

    // FIXME: should rename to new_function
    pub fn get_function(
        &self,
        name: &str,
        constants: Option<FunctionConstantValues>,
    ) -> Result<Function, String> {
        unsafe {
            let nsname = crate::nsstring_from_str(name);

            let function: *mut MTLFunction = match constants {
                Some(c) => try_objc! { err => msg_send![self,
                    newFunctionWithName: nsname.as_ref()
                    constantValues: c.as_ref()
                    error: &mut err
                ]},
                None => msg_send![self, newFunctionWithName: nsname.as_ref()],
            };

            if !function.is_null() {
                Ok(Function::from_ptr(function))
            } else {
                Err(format!("Function '{}' does not exist", name))
            }
        }
    }

    // TODO: get_function_async with completion handler

    pub fn function_names(&self) -> Vec<String> {
        unsafe {
            let names: *mut Object = msg_send![self, functionNames];
            let count: NSUInteger = msg_send![names, count];
            let ret = (0..count)
                .map(|i| {
                    let name = msg_send![names, objectAtIndex: i];
                    nsstring_as_str(name).to_string()
                })
                .collect();
            ret
        }
    }

    /// Only available on (macos(11.0), ios(14.0))
    pub fn library_type(&self) -> MTLLibraryType {
        unsafe { msg_send![self, type] }
    }

    /// Only available on (macos(11.0), ios(14.0))
    pub fn install_name(&self) -> Option<&str> {
        unsafe {
            let maybe_name: *mut Object = msg_send![self, installName];
            maybe_name.as_ref().map(crate::nsstring_as_str)
        }
    }

    /// Only available on (macos(11.0), ios(14.0))
    pub fn new_function_with_descriptor(
        &self,
        descriptor: &FunctionDescriptorRef,
    ) -> Result<Function, String> {
        unsafe {
            let function: *mut MTLFunction = try_objc! {
                err => msg_send![self,
                    newFunctionWithDescriptor: descriptor
                    error: &mut err
                ]
            };

            if !function.is_null() {
                Ok(Function::from_ptr(function))
            } else {
                Err(String::from("new_function_with_descriptor() failed"))
            }
        }
    }

    /// Only available on (macos(11.0), ios(14.0))
    pub fn new_intersection_function_with_descriptor(
        &self,
        descriptor: &IntersectionFunctionDescriptorRef,
    ) -> Result<Function, String> {
        unsafe {
            let function: *mut MTLFunction = try_objc! {
                err => msg_send![self,
                    newIntersectionFunctionWithDescriptor: descriptor
                    error: &mut err
                ]
            };

            if !function.is_null() {
                Ok(Function::from_ptr(function))
            } else {
                Err(String::from(
                    "new_intersection_function_with_descriptor() failed",
                ))
            }
        }
    }
}

/// Only available on (macos(11.0), ios(14.0))
///
/// See <https://developer.apple.com/documentation/metal/mtldynamiclibraryerror/>
#[repr(u64)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum MTLDynamicLibraryError {
    None = 0,
    InvalidFile = 1,
    CompilationFailure = 2,
    UnresolvedInstallName = 3,
    DependencyLoadFailure = 4,
    Unsupported = 5,
}

/// See <https://developer.apple.com/documentation/metal/mtldynamiclibrary/>
pub enum MTLDynamicLibrary {}

foreign_obj_type! {
    type CType = MTLDynamicLibrary;
    pub struct DynamicLibrary;
}

impl DynamicLibraryRef {
    pub fn device(&self) -> &DeviceRef {
        unsafe { msg_send![self, device] }
    }

    pub fn label(&self) -> &str {
        unsafe {
            let label = msg_send![self, label];
            crate::nsstring_as_str(label)
        }
    }

    pub fn set_label(&self, label: &str) {
        unsafe {
            let nslabel = crate::nsstring_from_str(label);
            let () = msg_send![self, setLabel: nslabel];
        }
    }

    pub fn install_name(&self) -> &str {
        unsafe {
            let name = msg_send![self, installName];
            crate::nsstring_as_str(name)
        }
    }

    pub fn serialize_to_url(&self, url: &URLRef) -> Result<bool, String> {
        unsafe { msg_send_bool_error_check![self, serializeToURL: url] }
    }
}

/// macOS 11.0+ iOS 14.0+
///
/// See <https://developer.apple.com/documentation/metal/mtlbinaryarchivedescriptor/>
pub enum MTLBinaryArchiveDescriptor {}

foreign_obj_type! {
    type CType = MTLBinaryArchiveDescriptor;
    pub struct BinaryArchiveDescriptor;
}

impl BinaryArchiveDescriptor {
    pub fn new() -> Self {
        unsafe {
            let class = class!(MTLBinaryArchiveDescriptor);
            msg_send![class, new]
        }
    }
}

impl BinaryArchiveDescriptorRef {
    pub fn url(&self) -> &URLRef {
        unsafe { msg_send![self, url] }
    }
    pub fn set_url(&self, url: &URLRef) {
        unsafe { msg_send![self, setUrl: url] }
    }
}

/// macOS 11.0+ iOS 14.0+
///
/// See <https://developer.apple.com/documentation/metal/mtlbinaryarchive/>
pub enum MTLBinaryArchive {}

foreign_obj_type! {
    type CType = MTLBinaryArchive;
    pub struct BinaryArchive;
}

impl BinaryArchiveRef {
    pub fn device(&self) -> &DeviceRef {
        unsafe { msg_send![self, device] }
    }

    pub fn label(&self) -> &str {
        unsafe {
            let label = msg_send![self, label];
            crate::nsstring_as_str(label)
        }
    }

    pub fn set_label(&self, label: &str) {
        unsafe {
            let nslabel = crate::nsstring_from_str(label);
            let () = msg_send![self, setLabel: nslabel];
        }
    }

    pub fn add_compute_pipeline_functions_with_descriptor(
        &self,
        descriptor: &ComputePipelineDescriptorRef,
    ) -> Result<bool, String> {
        unsafe {
            msg_send_bool_error_check![self, addComputePipelineFunctionsWithDescriptor: descriptor]
        }
    }

    pub fn add_render_pipeline_functions_with_descriptor(
        &self,
        descriptor: &RenderPipelineDescriptorRef,
    ) -> Result<bool, String> {
        unsafe {
            msg_send_bool_error_check![self, addRenderPipelineFunctionsWithDescriptor: descriptor]
        }
    }

    // TODO: addTileRenderPipelineFunctionsWithDescriptor
    // - (BOOL)addTileRenderPipelineFunctionsWithDescriptor:(MTLTileRenderPipelineDescriptor *)descriptor
    // error:(NSError * _Nullable *)error;

    pub fn serialize_to_url(&self, url: &URLRef) -> Result<bool, String> {
        unsafe {
            let mut err: *mut Object = ptr::null_mut();
            let result: BOOL = msg_send![self, serializeToURL:url
                                                        error:&mut err];
            if !err.is_null() {
                // FIXME: copy pasta
                let desc: *mut Object = msg_send![err, localizedDescription];
                let c_msg: *const c_char = msg_send![desc, UTF8String];
                let message = CStr::from_ptr(c_msg).to_string_lossy().into_owned();
                Err(message)
            } else {
                match result {
                    YES => Ok(true),
                    NO => Ok(false),
                    #[cfg(not(target_arch = "aarch64"))]
                    _ => unreachable!(),
                }
            }
        }
    }
}

/// macOS 11.0+ iOS 14.0+
///
/// See <https://developer.apple.com/documentation/metal/mtllinkedfunctions/>
pub enum MTLLinkedFunctions {}

foreign_obj_type! {
    type CType = MTLLinkedFunctions;
    pub struct LinkedFunctions;
}

impl LinkedFunctions {
    pub fn new() -> Self {
        unsafe {
            let class = class!(MTLLinkedFunctions);
            msg_send![class, new]
        }
    }
}

impl LinkedFunctionsRef {
    /// Marshal to Rust Vec
    pub fn functions(&self) -> Vec<Function> {
        unsafe {
            let functions: *mut Object = msg_send![self, functions];
            let count: NSUInteger = msg_send![functions, count];
            let ret = (0..count)
                .map(|i| {
                    let f = msg_send![functions, objectAtIndex: i];
                    Function::from_ptr(f)
                })
                .collect();
            ret
        }
    }

    /// Marshal from Rust slice
    pub fn set_functions(&self, functions: &[&FunctionRef]) {
        let ns_array = Array::<Function>::from_slice(functions);
        unsafe { msg_send![self, setFunctions: ns_array] }
    }

    /// Marshal to Rust Vec
    pub fn binary_functions(&self) -> Vec<Function> {
        unsafe {
            let functions: *mut Object = msg_send![self, binaryFunctions];
            let count: NSUInteger = msg_send![functions, count];
            let ret = (0..count)
                .map(|i| {
                    let f = msg_send![functions, objectAtIndex: i];
                    Function::from_ptr(f)
                })
                .collect();
            ret
        }
    }

    /// Marshal from Rust slice
    pub fn set_binary_functions(&self, functions: &[&FunctionRef]) {
        let ns_array = Array::<Function>::from_slice(functions);
        unsafe { msg_send![self, setBinaryFunctions: ns_array] }
    }

    // TODO: figure out NSDictionary wrapper
    // TODO: groups
    // @property (readwrite, nonatomic, copy, nullable) NSDictionary<NSString*, NSArray<id<MTLFunction>>*> *groups;
}

[ Dauer der Verarbeitung: 0.33 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge