//! 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::*;

/// Represents a timestamp data entry in a counter heap of type `MTL4CounterHeapTypeTimestamp`.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtl4timestampheapentry?language=objc)
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct MTL4TimestampHeapEntry {
    pub timestamp: u64,
}

unsafe impl Encode for MTL4TimestampHeapEntry {
    const ENCODING: Encoding = Encoding::Struct("?", &[<u64>::ENCODING]);
}

unsafe impl RefEncode for MTL4TimestampHeapEntry {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// Defines the type of a ``MTL4CounterHeap`` and the contents of its entries.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtl4counterheaptype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTL4CounterHeapType(pub NSInteger);
impl MTL4CounterHeapType {
    /// Specifies that ``MTL4CounterHeap`` entries contain invalid data.
    #[doc(alias = "MTL4CounterHeapTypeInvalid")]
    pub const Invalid: Self = Self(0);
    /// Specifies that ``MTL4CounterHeap`` entries contain GPU timestamp data.
    #[doc(alias = "MTL4CounterHeapTypeTimestamp")]
    pub const Timestamp: Self = Self(1);
}

unsafe impl Encode for MTL4CounterHeapType {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for MTL4CounterHeapType {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// Provides a hint to the system about the desired accuracy when writing GPU counter timestamps.
///
/// Pass these values to ``MTL4ComputeCommandEncoder/writeTimestampWithGranularity:intoHeap:atIndex:`` and
/// ``MTL4RenderCommandEncoder/writeTimestampWithGranularity:afterStage:intoHeap:atIndex:`` to control the
/// desired accurracy of the counter sampling operation.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtl4timestampgranularity?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTL4TimestampGranularity(pub NSInteger);
impl MTL4TimestampGranularity {
    /// A minimally-invasive timestamp which may be less precise.
    ///
    /// Using this granularity incurs in the lowest overhead, at the cost of precision. For example, it may sample at
    /// command encoder boundaries.
    #[doc(alias = "MTL4TimestampGranularityRelaxed")]
    pub const Relaxed: Self = Self(0);
    /// A timestamp as precise as possible.
    ///
    /// Using this granularity may incur in a performance penalty, for example, it may cause splitting of command encoders.
    #[doc(alias = "MTL4TimestampGranularityPrecise")]
    pub const Precise: Self = Self(1);
}

unsafe impl Encode for MTL4TimestampGranularity {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for MTL4TimestampGranularity {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// Groups together parameters for configuring a counter heap object at creation time.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtl4counterheapdescriptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTL4CounterHeapDescriptor;
);

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

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

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

impl MTL4CounterHeapDescriptor {
    extern_methods!(
        /// Assigns the type of data that the heap contains.
        #[unsafe(method(type))]
        #[unsafe(method_family = none)]
        pub fn r#type(&self) -> MTL4CounterHeapType;

        /// Setter for [`type`][Self::type].
        #[unsafe(method(setType:))]
        #[unsafe(method_family = none)]
        pub fn setType(&self, r#type: MTL4CounterHeapType);

        /// Assigns the number of entries in the heap.
        ///
        /// Each entry represents one item in the heap. The size of the individual entries depends on the heap type.
        #[unsafe(method(count))]
        #[unsafe(method_family = none)]
        pub fn count(&self) -> NSUInteger;

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

/// Methods declared on superclass `NSObject`.
impl MTL4CounterHeapDescriptor {
    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 MTL4CounterHeapDescriptor {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_protocol!(
    /// Represents an opaque, driver-controlled section of memory that can store GPU counter data.
    ///
    /// The data instances that this type stores correspond to the ``MTL4CounterHeapType`` heap type that you assign at creation time.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtl4counterheap?language=objc)
    pub unsafe trait MTL4CounterHeap: NSObjectProtocol {
        /// Assigns a label for later inspection or visualization.
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        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)]
        fn setLabel(&self, label: Option<&NSString>);

        /// Queries the number of entries in the heap.
        #[unsafe(method(count))]
        #[unsafe(method_family = none)]
        fn count(&self) -> NSUInteger;

        /// Queries the type of the heap.
        #[unsafe(method(type))]
        #[unsafe(method_family = none)]
        fn r#type(&self) -> MTL4CounterHeapType;

        /// Resolves heap data on the CPU timeline.
        ///
        /// This method resolves heap data in the CPU timeline. Your app needs to ensure the GPU work has completed in order to
        /// retrieve the data correctly. You can alternatively resolve the heap data in the GPU timeline by calling
        /// ``MTL4CommandBuffer/resolveCounterHeap:withRange:intoBuffer:waitFence:updateFence:``.
        ///
        /// - Note: When resolving counters in the CPU timeline, signaling an instance of ``MTLSharedEvent`` after any workloads
        /// write counters (and waiting on that signal on the CPU) is sufficient to ensure synchronization.
        ///
        /// - Parameter range: The range in the heap to resolve.
        /// - Returns a newly allocated autoreleased NSData containing tightly packed resolved heap counter values.
        ///
        /// # Safety
        ///
        /// `range` might not be bounds-checked.
        #[unsafe(method(resolveCounterRange:))]
        #[unsafe(method_family = none)]
        unsafe fn resolveCounterRange(&self, range: NSRange) -> Option<Retained<NSData>>;

        /// Invalidates a range of entries in this counter heap.
        ///
        /// The effect of this call is immediate on the CPU timeline. You are responsible for ensuring that this counter heap is not currently in use on the GPU.
        ///
        /// - Note: Invalidated entries produce 0 when resolved.
        ///
        /// - Parameters:
        /// - range: A heap index range to invalidate.
        ///
        /// # Safety
        ///
        /// `range` might not be bounds-checked.
        #[unsafe(method(invalidateCounterRange:))]
        #[unsafe(method_family = none)]
        unsafe fn invalidateCounterRange(&self, range: NSRange);
    }
);
