using System; using System.Runtime.InteropServices; using Unity.Collections; namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler { /// /// A fixed-size array that can contain up to maximum render target attachment amount of items. /// /// The type of data to store in the array. [StructLayout(LayoutKind.Sequential)] public struct FixedAttachmentArray where DataType : unmanaged { /// /// Returns an empty array. /// public static FixedAttachmentArray Empty = new FixedAttachmentArray(0); /// /// The maximum number of elements that can be stored in the array. /// public const int MaxAttachments = 8; /// This is a fixed size struct that emulates itself as an array /// similar to how Unity.Math emulates fixed size arrays private DataType a0, a1, a2, a3, a4, a5, a6, a7; private int activeAttachments; /// /// Created an new array with the specified number of attachments. /// /// Number of attachments to consider valid. /// Thrown if the amount of elements is less than 0 or more than MaxAttachments public FixedAttachmentArray(int numAttachments) { #if DEVELOPMENT_BUILD || UNITY_EDITOR if (numAttachments < 0 || numAttachments > MaxAttachments) { throw new ArgumentException($"FixedAttachmentArray - numAttachments must be in range of [0, {MaxAttachments}["); } #endif a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = new DataType(); activeAttachments = numAttachments; } /// /// Intialize the FixedAttachmentArray by copying data from the passed in c# array. /// /// The C# array from which to copy the elements. public FixedAttachmentArray(DataType[] attachments) : this(attachments.Length) { for (int i = 0; i < activeAttachments; ++i) { this[i] = attachments[i]; } } /// /// Intialize the FixedAttachmentArray by copying data from the passed in native array. /// /// The native array from which to copy the elements. public FixedAttachmentArray(NativeArray attachments) : this(attachments.Length) { for (int i = 0; i < activeAttachments; ++i) { this[i] = attachments[i]; } } /// /// Number of attachments in the array alway less or equal than MaxAttachments /// public int size { get { return activeAttachments; } } /// /// Clear the array. /// public void Clear() { activeAttachments = 0; } /// /// Add an element tot the array. /// /// Element to add /// Returns the index where the item was added. /// If the maximum amount of elements (MaxAttachments) is reached. public int Add(in DataType data) { #if DEVELOPMENT_BUILD || UNITY_EDITOR if ((uint)activeAttachments >= MaxAttachments) throw new IndexOutOfRangeException($"A FixedAttachmentArray can only contain {MaxAttachments} items."); #endif int index = activeAttachments; unsafe { fixed (FixedAttachmentArray* self = &this) { DataType* array = (DataType*)self; array[index] = data; } } activeAttachments++; return index; } /// /// Get the element at the specified index in the array. /// /// Index of the element. /// The value of the element. /// If the index is outside the valid range. public ref DataType this[int index] { get { #if DEVELOPMENT_BUILD || UNITY_EDITOR if ((uint)index >= MaxAttachments) throw new IndexOutOfRangeException($"FixedAttachmentArray - index must be in range of [0, {MaxAttachments}["); if ((uint)index >= activeAttachments) throw new IndexOutOfRangeException($"FixedAttachmentArray - index must be in range of [0, {activeAttachments}["); #endif unsafe { fixed (FixedAttachmentArray* self = &this) { DataType* array = (DataType*)self; return ref array[index]; } } } } } }