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];
}
}
}
}
}
}