using System.Collections.Generic;
using System.Collections;
using System;
namespace UnityEngine.Animations.Rigging
{
///
/// This struct defines a List of WeightedTransform.
/// WeightedTransformArray can be animated (as opposed to System.List and C# arrays) and is implemented
/// with a hard limit of eight WeightedTransform elements.
/// See also and .
///
[Serializable]
public struct WeightedTransformArray : IList, IList
{
/// Maximum number of elements in WeightedTransformArray.
public static readonly int k_MaxLength = 8;
[SerializeField, NotKeyable] private int m_Length;
[SerializeField] private WeightedTransform m_Item0;
[SerializeField] private WeightedTransform m_Item1;
[SerializeField] private WeightedTransform m_Item2;
[SerializeField] private WeightedTransform m_Item3;
[SerializeField] private WeightedTransform m_Item4;
[SerializeField] private WeightedTransform m_Item5;
[SerializeField] private WeightedTransform m_Item6;
[SerializeField] private WeightedTransform m_Item7;
///
/// Constructor.
///
/// Size of the array. This will clamped to be a number in between 0 and k_MaxLength.
///
public WeightedTransformArray(int size)
{
m_Length = ClampSize(size);
m_Item0 = new WeightedTransform();
m_Item1 = new WeightedTransform();
m_Item2 = new WeightedTransform();
m_Item3 = new WeightedTransform();
m_Item4 = new WeightedTransform();
m_Item5 = new WeightedTransform();
m_Item6 = new WeightedTransform();
m_Item7 = new WeightedTransform();
}
///
/// Returns an enumerator that iterates through a collection.
///
/// An IEnumerator object that can be used to iterate through the collection.
public IEnumerator GetEnumerator()
{
return new Enumerator(ref this);
}
///
/// Returns an enumerator that iterates through a collection.
///
/// An IEnumerator object that can be used to iterate through the collection.
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(ref this);
}
///
/// Adds an item to the WeightedTransformArray.
///
/// The object to add to the WeightedTransformArray.
/// The position into which the new element was inserted, or -1 to indicate that the item was not inserted into the collection.
int IList.Add(object value)
{
Add((WeightedTransform)value);
return m_Length - 1;
}
///
/// Adds an item to the WeightedTransformArray.
///
/// The WeightedTransform to add to the WeightedTransformArray.
public void Add(WeightedTransform value)
{
if (m_Length >= k_MaxLength)
throw new ArgumentException($"This array cannot have more than '{k_MaxLength}' items.");
Set(m_Length, value);
++m_Length;
}
///
/// Removes all items from the WeightedTransformArray.
///
public void Clear()
{
m_Length = 0;
}
///
/// Determines the index of a specific item in the WeightedTransformArray.
///
/// The object to locate in the WeightedTransformArray.
/// The index of value if found in the list; otherwise, -1.
int IList.IndexOf(object value) => IndexOf((WeightedTransform)value);
///
/// Determines the index of a specific item in the WeightedTransformArray.
///
/// The WeightedTransform to locate in the WeightedTransformArray.
/// The index of value if found in the list; otherwise, -1.
public int IndexOf(WeightedTransform value)
{
for (int i = 0; i < m_Length; ++i)
{
if (Get(i).Equals(value))
return i;
}
return -1;
}
///
/// Determines whether the WeightedTransformArray contains a specific value.
///
/// The object to locate in the WeightedTransformArray.
/// true if the Object is found in the WeightedTransformArray; otherwise, false.
bool IList.Contains(object value) => Contains((WeightedTransform)value);
///
/// Determines whether the WeightedTransformArray contains a specific value.
///
/// The WeightedTransform to locate in the WeightedTransformArray.
/// true if the Object is found in the WeightedTransformArray; otherwise, false.
public bool Contains(WeightedTransform value)
{
for (int i = 0; i < m_Length; ++i)
{
if (Get(i).Equals(value))
return true;
}
return false;
}
///
/// Copies the elements of the WeightedTransform to an Array, starting at a particular Array index.
///
/// The one-dimensional Array that is the destination of the elements copied from WeightedTransform. The Array must have zero-based indexing.
/// The zero-based index in array at which copying begins.
void ICollection.CopyTo(Array array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException("The array cannot be null.");
if (arrayIndex < 0)
throw new ArgumentOutOfRangeException("The starting array index cannot be negative.");
if (Count > array.Length - arrayIndex + 1)
throw new ArgumentException("The destination array has fewer elements than the collection.");
for (int i = 0; i < m_Length; i++)
{
array.SetValue(Get(i), i + arrayIndex);
}
}
///
/// Copies the elements of the WeightedTransform to an Array, starting at a particular Array index.
///
/// The one-dimensional Array that is the destination of the elements copied from WeightedTransform. The Array must have zero-based indexing.
/// The zero-based index in array at which copying begins.
public void CopyTo(WeightedTransform[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException("The array cannot be null.");
if (arrayIndex < 0)
throw new ArgumentOutOfRangeException("The starting array index cannot be negative.");
if (Count > array.Length - arrayIndex + 1)
throw new ArgumentException("The destination array has fewer elements than the collection.");
for (int i = 0; i < m_Length; i++)
{
array[i + arrayIndex] = Get(i);
}
}
///
/// Removes the first occurrence of a specific object from the WeightedTransformArray.
///
/// The object to remove from the WeightedTransformArray.
void IList.Remove(object value) { Remove((WeightedTransform)value); }
///
/// Removes the first occurrence of a specific WeightedTransform from the WeightedTransformArray.
///
/// The WeightedTransform to remove from the WeightedTransformArray.
/// True if value was removed from the array, false otherwise.
public bool Remove(WeightedTransform value)
{
for (int i = 0; i < m_Length; ++i)
{
if (Get(i).Equals(value))
{
for (; i < m_Length - 1; ++i)
{
Set(i, Get(i + 1));
}
--m_Length;
return true;
}
}
return false;
}
///
/// Removes the WeightedTransformArray item at the specified index.
///
/// The zero-based index of the item to remove.
public void RemoveAt(int index)
{
CheckOutOfRangeIndex(index);
for (int i = index; i < m_Length - 1; ++i)
{
Set(i, Get(i + 1));
}
--m_Length;
}
///
/// Inserts an item to the WeightedTransformArray at the specified index.
///
/// The zero-based index at which value should be inserted.
/// The object to insert into the WeightedTransformArray.
void IList.Insert(int index, object value) => Insert(index, (WeightedTransform)value);
///
/// Inserts an item to the WeightedTransformArray at the specified index.
///
/// The zero-based index at which value should be inserted.
/// The WeightedTransform to insert into the WeightedTransformArray.
public void Insert(int index, WeightedTransform value)
{
if (m_Length >= k_MaxLength)
throw new ArgumentException($"This array cannot have more than '{k_MaxLength}' items.");
CheckOutOfRangeIndex(index);
if (index >= m_Length)
{
Add(value);
return;
}
for (int i = m_Length; i > index; --i)
{
Set(i, Get(i - 1));
}
Set(index, value);
++m_Length;
}
///
/// Clamps specified value in between 0 and k_MaxLength.
///
/// Size value.
/// Value in between 0 and k_MaxLength.
///
private static int ClampSize(int size)
{
return Mathf.Clamp(size, 0, k_MaxLength);
}
///
/// Checks whether specified index value in within bounds.
///
/// Index value.
/// Index value is not between 0 and k_MaxLength.
///
private void CheckOutOfRangeIndex(int index)
{
if (index < 0 || index >= k_MaxLength)
throw new IndexOutOfRangeException($"Index {index} is out of range of '{m_Length}' Length.");
}
///
/// Retrieves a WeightedTransform at specified index.
///
/// Index value.
/// The WeightedTransform value at specified index.
private WeightedTransform Get(int index)
{
CheckOutOfRangeIndex(index);
switch(index)
{
case 0: return m_Item0;
case 1: return m_Item1;
case 2: return m_Item2;
case 3: return m_Item3;
case 4: return m_Item4;
case 5: return m_Item5;
case 6: return m_Item6;
case 7: return m_Item7;
}
// Shouldn't happen.
return m_Item0;
}
///
/// Sets a WeightedTransform at specified index.
///
/// Index value.
/// The WeightedTransform value to set.
private void Set(int index, WeightedTransform value)
{
CheckOutOfRangeIndex(index);
switch(index)
{
case 0: m_Item0 = value; break;
case 1: m_Item1 = value; break;
case 2: m_Item2 = value; break;
case 3: m_Item3 = value; break;
case 4: m_Item4 = value; break;
case 5: m_Item5 = value; break;
case 6: m_Item6 = value; break;
case 7: m_Item7 = value; break;
}
}
///
/// Sets a weight on a WeightedTransform at specified index.
///
/// Index value.
/// The weight value to set.
public void SetWeight(int index, float weight)
{
var weightedTransform = Get(index);
weightedTransform.weight = weight;
Set(index, weightedTransform);
}
///
/// Retrieves a weight on a WeightedTransform at specified index.
///
/// Index value.
/// The weight value at specified index.
public float GetWeight(int index)
{
return Get(index).weight;
}
///
/// Sets the Transform reference on a WeightedTransform at specified index.
///
/// Index value.
/// The Transform reference to set.
public void SetTransform(int index, Transform transform)
{
var weightedTransform = Get(index);
weightedTransform.transform = transform;
Set(index, weightedTransform);
}
///
/// Retrieves a Transform reference on a WeightedTransform at specified index.
///
/// Index value.
/// The Transform reference at specified index.
public Transform GetTransform(int index)
{
return Get(index).transform;
}
///
/// Method to call from a provider's OnValidate() callback to ensure all weight values are within the valid range.
/// See also .
///
/// WeightedTransformArray to adjust.
/// Minimum value to clamp array values with.
/// Maximum value to clamp array values with.
public static void OnValidate(ref WeightedTransformArray array, float min = 0f, float max = 1f)
{
for (var i = 0; i < k_MaxLength; ++i)
array.SetWeight(i, Mathf.Clamp(array.GetWeight(i), min, max));
}
///
/// Gets or sets the element at the specified index.
///
/// The zero-based index of the element to get or set.
object IList.this[int index] { get => (object)Get(index); set => Set(index, (WeightedTransform)value); }
///
/// Gets or sets the WeightedTransform at the specified index.
///
/// The zero-based index of the WeightedTransform to get or set.
public WeightedTransform this[int index] { get => Get(index); set => Set(index, value); }
/// The number of elements contained in the WeightedTransformArray.
public int Count { get => m_Length; }
///
/// Retrieves whether WeightedTransformArray is read-only. Always false.
///
public bool IsReadOnly { get => false; }
///
/// Retrieves whether WeightedTransformArray has a fixed size. Always false.
///
public bool IsFixedSize { get => false; }
bool ICollection.IsSynchronized { get => true; }
object ICollection.SyncRoot { get => null; }
[System.Serializable]
private struct Enumerator : IEnumerator
{
private WeightedTransformArray m_Array;
private int m_Index;
public Enumerator(ref WeightedTransformArray array)
{
m_Array = array;
m_Index = -1;
}
public bool MoveNext()
{
m_Index++;
return (m_Index < m_Array.Count);
}
public void Reset()
{
m_Index = -1;
}
void IDisposable.Dispose() { }
public WeightedTransform Current => m_Array.Get(m_Index);
object IEnumerator.Current => Current;
}
}
}