//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
use objc2_foundation::*;

use crate::*;

extern_class!(
    /// Specifies the parameters for MTLResidencySet creation.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlresidencysetdescriptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLResidencySetDescriptor;
);

extern_conformance!(
    unsafe impl NSCopying for MTLResidencySetDescriptor {}
);

unsafe impl CopyingHelper for MTLResidencySetDescriptor {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLResidencySetDescriptor {}
);

impl MTLResidencySetDescriptor {
    extern_methods!(
        /// An optional label for the MTLResidencySet.
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        pub fn label(&self) -> Option<Retained<NSString>>;

        /// Setter for [`label`][Self::label].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setLabel:))]
        #[unsafe(method_family = none)]
        pub fn setLabel(&self, label: Option<&NSString>);

        /// If non-zero, defines the number of allocations for which to initialize the internal arrays. Defaults to zero.
        #[unsafe(method(initialCapacity))]
        #[unsafe(method_family = none)]
        pub fn initialCapacity(&self) -> NSUInteger;

        /// Setter for [`initialCapacity`][Self::initialCapacity].
        ///
        /// # Safety
        ///
        /// This might not be bounds-checked.
        #[unsafe(method(setInitialCapacity:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setInitialCapacity(&self, initial_capacity: NSUInteger);
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLResidencySetDescriptor {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

impl DefaultRetained for MTLResidencySetDescriptor {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_protocol!(
    /// A residency set is responsible for managing resource and heap residency and is referenced
    /// by a command buffer or command queue in order to ensure that resources and heaps are resident.
    /// Resources and heaps are added and removed uncommitted and a subsequent commit call applies all
    /// of the changes in bulk.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlresidencyset?language=objc)
    pub unsafe trait MTLResidencySet: NSObjectProtocol {
        #[cfg(feature = "MTLDevice")]
        /// The device that created the residency set
        #[unsafe(method(device))]
        #[unsafe(method_family = none)]
        fn device(&self) -> Retained<ProtocolObject<dyn MTLDevice>>;

        /// The label specified at creation.
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        fn label(&self) -> Option<Retained<NSString>>;

        /// The memory footprint of the set in bytes at the last commit operation. This may include internal allocations as well.
        #[unsafe(method(allocatedSize))]
        #[unsafe(method_family = none)]
        fn allocatedSize(&self) -> u64;

        /// Requests that the set and all the committed resources and heaps are made resident.
        #[unsafe(method(requestResidency))]
        #[unsafe(method_family = none)]
        fn requestResidency(&self);

        /// Requests that the set and all the committed resources and heaps are made non-resident.
        #[unsafe(method(endResidency))]
        #[unsafe(method_family = none)]
        fn endResidency(&self);

        #[cfg(feature = "MTLAllocation")]
        /// Adds one allocation to the set, leaving it uncommitted until commit is called.
        #[unsafe(method(addAllocation:))]
        #[unsafe(method_family = none)]
        fn addAllocation(&self, allocation: &ProtocolObject<dyn MTLAllocation>);

        #[cfg(feature = "MTLAllocation")]
        /// Adds allocations to the set, leaving them uncommitted until commit is called.
        ///
        /// # Safety
        ///
        /// - `allocations` must be a valid pointer.
        /// - `count` might not be bounds-checked.
        #[unsafe(method(addAllocations:count:))]
        #[unsafe(method_family = none)]
        unsafe fn addAllocations_count(
            &self,
            allocations: NonNull<NonNull<ProtocolObject<dyn MTLAllocation>>>,
            count: NSUInteger,
        );

        #[cfg(feature = "MTLAllocation")]
        /// Marks an allocation to be removed from the set on the next commit call.
        #[unsafe(method(removeAllocation:))]
        #[unsafe(method_family = none)]
        fn removeAllocation(&self, allocation: &ProtocolObject<dyn MTLAllocation>);

        #[cfg(feature = "MTLAllocation")]
        /// Marks allocations to be removed from the set on the next commit call.
        ///
        /// # Safety
        ///
        /// - `allocations` must be a valid pointer.
        /// - `count` might not be bounds-checked.
        #[unsafe(method(removeAllocations:count:))]
        #[unsafe(method_family = none)]
        unsafe fn removeAllocations_count(
            &self,
            allocations: NonNull<NonNull<ProtocolObject<dyn MTLAllocation>>>,
            count: NSUInteger,
        );

        /// Marks all allocations to be removed from the set on the next commit call.
        #[unsafe(method(removeAllAllocations))]
        #[unsafe(method_family = none)]
        fn removeAllAllocations(&self);

        #[cfg(feature = "MTLAllocation")]
        /// Returns a boolean indicating whether the allocation is present in the set or not.
        ///
        /// This check includes non-committed allocations in the set.
        #[unsafe(method(containsAllocation:))]
        #[unsafe(method_family = none)]
        fn containsAllocation(&self, an_allocation: &ProtocolObject<dyn MTLAllocation>) -> bool;

        #[cfg(feature = "MTLAllocation")]
        /// Array of all allocations associated with the set.
        ///
        /// This property includes non-committed allocations in the set.
        #[unsafe(method(allAllocations))]
        #[unsafe(method_family = none)]
        fn allAllocations(&self) -> Retained<NSArray<ProtocolObject<dyn MTLAllocation>>>;

        /// Returns the current number of unique allocations present in the set.
        ///
        /// This property includes non-committed allocations in the set.
        #[unsafe(method(allocationCount))]
        #[unsafe(method_family = none)]
        fn allocationCount(&self) -> NSUInteger;

        /// Commits any pending adds/removes.
        ///
        /// If the residency set is resident, this will try to make added resources and heaps resident instantly, and make removed resources and heaps non-resident.
        #[unsafe(method(commit))]
        #[unsafe(method_family = none)]
        fn commit(&self);
    }
);
