//---------------------------------------------- 
 | 
//            NGUI: Next-Gen UI kit 
 | 
// Copyright © 2011-2014 Tasharen Entertainment 
 | 
//---------------------------------------------- 
 | 
  
 | 
using UnityEngine; 
 | 
using System.Collections.Generic; 
 | 
using System.Diagnostics; 
 | 
  
 | 
/// <summary> 
 | 
/// This improved version of the System.Collections.Generic.List that doesn't release the buffer on Clear(), resulting in better performance and less garbage collection. 
 | 
/// </summary> 
 | 
  
 | 
public class BetterList<T> 
 | 
{ 
 | 
#if UNITY_FLASH 
 | 
  
 | 
    List<T> mList = new List<T>(); 
 | 
     
 | 
    /// <summary> 
 | 
    /// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size. 
 | 
    /// </summary> 
 | 
     
 | 
    public T this[int i] 
 | 
    { 
 | 
        get { return mList[i]; } 
 | 
        set { mList[i] = value; } 
 | 
    } 
 | 
     
 | 
    /// <summary> 
 | 
    /// Compatibility with the non-flash syntax. 
 | 
    /// </summary> 
 | 
     
 | 
    public List<T> buffer { get { return mList; } } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Direct access to the buffer's size. Note that it's only public for speed and efficiency. You shouldn't modify it. 
 | 
    /// </summary> 
 | 
  
 | 
    public int size { get { return mList.Count; } } 
 | 
  
 | 
    /// <summary> 
 | 
    /// For 'foreach' functionality. 
 | 
    /// </summary> 
 | 
  
 | 
    public IEnumerator<T> GetEnumerator () { return mList.GetEnumerator(); } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Clear the array by resetting its size to zero. Note that the memory is not actually released. 
 | 
    /// </summary> 
 | 
  
 | 
    public void Clear () { mList.Clear(); } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Clear the array and release the used memory. 
 | 
    /// </summary> 
 | 
  
 | 
    public void Release () { mList.Clear(); } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Add the specified item to the end of the list. 
 | 
    /// </summary> 
 | 
  
 | 
    public void Add (T item) { mList.Add(item); } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Insert an item at the specified index, pushing the entries back. 
 | 
    /// </summary> 
 | 
  
 | 
    public void Insert (int index, T item) { mList.Insert(index, item); } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Returns 'true' if the specified item is within the list. 
 | 
    /// </summary> 
 | 
  
 | 
    public bool Contains (T item) { return mList.Contains(item); } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index. 
 | 
    /// </summary> 
 | 
  
 | 
    public bool Remove (T item) { return mList.Remove(item); } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Remove an item at the specified index. 
 | 
    /// </summary> 
 | 
  
 | 
    public void RemoveAt (int index) { mList.RemoveAt(index); } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Remove an item from the end. 
 | 
    /// </summary> 
 | 
  
 | 
    public T Pop () 
 | 
    { 
 | 
        if (buffer != null && size != 0) 
 | 
        { 
 | 
            T val = buffer[mList.Count - 1]; 
 | 
            mList.RemoveAt(mList.Count - 1); 
 | 
            return val; 
 | 
        } 
 | 
        return default(T); 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size. 
 | 
    /// </summary> 
 | 
  
 | 
    public T[] ToArray () { return mList.ToArray(); } 
 | 
  
 | 
    /// <summary> 
 | 
    /// List.Sort equivalent. 
 | 
    /// </summary> 
 | 
  
 | 
    public void Sort (System.Comparison<T> comparer) { mList.Sort(comparer); } 
 | 
  
 | 
#else 
 | 
  
 | 
    /// <summary> 
 | 
    /// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size. 
 | 
    /// </summary> 
 | 
  
 | 
    public T[] buffer; 
 | 
  
 | 
    /// <summary> 
 | 
    /// Direct access to the buffer's size. Note that it's only public for speed and efficiency. You shouldn't modify it. 
 | 
    /// </summary> 
 | 
  
 | 
    public int size = 0; 
 | 
  
 | 
    /// <summary> 
 | 
    /// For 'foreach' functionality. 
 | 
    /// </summary> 
 | 
  
 | 
    [DebuggerHidden] 
 | 
    [DebuggerStepThrough] 
 | 
    public IEnumerator<T> GetEnumerator () 
 | 
    { 
 | 
        if (buffer != null) 
 | 
        { 
 | 
            for (int i = 0; i < size; ++i) 
 | 
            { 
 | 
                yield return buffer[i]; 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
     
 | 
    /// <summary> 
 | 
    /// Convenience function. I recommend using .buffer instead. 
 | 
    /// </summary> 
 | 
  
 | 
    [DebuggerHidden] 
 | 
    public T this[int i] 
 | 
    { 
 | 
        get { return buffer[i]; } 
 | 
        set { buffer[i] = value; } 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Helper function that expands the size of the array, maintaining the content. 
 | 
    /// </summary> 
 | 
  
 | 
    void AllocateMore () 
 | 
    { 
 | 
        T[] newList = (buffer != null) ? new T[Mathf.Max(buffer.Length << 1, 32)] : new T[32]; 
 | 
        if (buffer != null && size > 0) buffer.CopyTo(newList, 0); 
 | 
        buffer = newList; 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Trim the unnecessary memory, resizing the buffer to be of 'Length' size. 
 | 
    /// Call this function only if you are sure that the buffer won't need to resize anytime soon. 
 | 
    /// </summary> 
 | 
  
 | 
    void Trim () 
 | 
    { 
 | 
        if (size > 0) 
 | 
        { 
 | 
            if (size < buffer.Length) 
 | 
            { 
 | 
                T[] newList = new T[size]; 
 | 
                for (int i = 0; i < size; ++i) newList[i] = buffer[i]; 
 | 
                buffer = newList; 
 | 
            } 
 | 
        } 
 | 
        else buffer = null; 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Clear the array by resetting its size to zero. Note that the memory is not actually released. 
 | 
    /// </summary> 
 | 
  
 | 
    public void Clear () { size = 0; } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Clear the array and release the used memory. 
 | 
    /// </summary> 
 | 
  
 | 
    public void Release () { size = 0; buffer = null; } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Add the specified item to the end of the list. 
 | 
    /// </summary> 
 | 
  
 | 
    public void Add (T item) 
 | 
    { 
 | 
        if (buffer == null || size == buffer.Length) AllocateMore(); 
 | 
        buffer[size++] = item; 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Insert an item at the specified index, pushing the entries back. 
 | 
    /// </summary> 
 | 
  
 | 
    public void Insert (int index, T item) 
 | 
    { 
 | 
        if (buffer == null || size == buffer.Length) AllocateMore(); 
 | 
  
 | 
        if (index < size) 
 | 
        { 
 | 
            for (int i = size; i > index; --i) buffer[i] = buffer[i - 1]; 
 | 
            buffer[index] = item; 
 | 
            ++size; 
 | 
        } 
 | 
        else Add(item); 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Returns 'true' if the specified item is within the list. 
 | 
    /// </summary> 
 | 
  
 | 
    public bool Contains (T item) 
 | 
    { 
 | 
        if (buffer == null) return false; 
 | 
        for (int i = 0; i < size; ++i) if (buffer[i].Equals(item)) return true; 
 | 
        return false; 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index. 
 | 
    /// </summary> 
 | 
  
 | 
    public bool Remove (T item) 
 | 
    { 
 | 
        if (buffer != null) 
 | 
        { 
 | 
            EqualityComparer<T> comp = EqualityComparer<T>.Default; 
 | 
  
 | 
            for (int i = 0; i < size; ++i) 
 | 
            { 
 | 
                if (comp.Equals(buffer[i], item)) 
 | 
                { 
 | 
                    --size; 
 | 
                    buffer[i] = default(T); 
 | 
                    for (int b = i; b < size; ++b) buffer[b] = buffer[b + 1]; 
 | 
                    buffer[size] = default(T); 
 | 
                    return true; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
        return false; 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Remove an item at the specified index. 
 | 
    /// </summary> 
 | 
  
 | 
    public void RemoveAt (int index) 
 | 
    { 
 | 
        if (buffer != null && index < size) 
 | 
        { 
 | 
            --size; 
 | 
            buffer[index] = default(T); 
 | 
            for (int b = index; b < size; ++b) buffer[b] = buffer[b + 1]; 
 | 
            buffer[size] = default(T); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Remove an item from the end. 
 | 
    /// </summary> 
 | 
  
 | 
    public T Pop () 
 | 
    { 
 | 
        if (buffer != null && size != 0) 
 | 
        { 
 | 
            T val = buffer[--size]; 
 | 
            buffer[size] = default(T); 
 | 
            return val; 
 | 
        } 
 | 
        return default(T); 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size. 
 | 
    /// </summary> 
 | 
  
 | 
    public T[] ToArray () { Trim(); return buffer; } 
 | 
  
 | 
    //class Comparer : System.Collections.IComparer 
 | 
    //{ 
 | 
    //    public System.Comparison<T> func; 
 | 
    //    public int Compare (object x, object y) { return func((T)x, (T)y); } 
 | 
    //} 
 | 
  
 | 
    //Comparer mComp = new Comparer(); 
 | 
  
 | 
    /// <summary> 
 | 
    /// List.Sort equivalent. Doing Array.Sort causes GC allocations. 
 | 
    /// </summary> 
 | 
  
 | 
    //public void Sort (System.Comparison<T> comparer) 
 | 
    //{ 
 | 
    //    if (size > 0) 
 | 
    //    { 
 | 
    //        mComp.func = comparer; 
 | 
    //        System.Array.Sort(buffer, 0, size, mComp); 
 | 
    //    } 
 | 
    //} 
 | 
  
 | 
    /// <summary> 
 | 
    /// List.Sort equivalent. Manual sorting causes no GC allocations. 
 | 
    /// </summary> 
 | 
  
 | 
    [DebuggerHidden] 
 | 
    [DebuggerStepThrough] 
 | 
    public void Sort (CompareFunc comparer) 
 | 
    { 
 | 
        int start = 0; 
 | 
        int max = size - 1; 
 | 
        bool changed = true; 
 | 
  
 | 
        while (changed) 
 | 
        { 
 | 
            changed = false; 
 | 
  
 | 
            for (int i = start; i < max; ++i) 
 | 
            { 
 | 
                // Compare the two values 
 | 
                if (comparer(buffer[i], buffer[i + 1]) > 0) 
 | 
                { 
 | 
                    // Swap the values 
 | 
                    T temp = buffer[i]; 
 | 
                    buffer[i] = buffer[i + 1]; 
 | 
                    buffer[i + 1] = temp; 
 | 
                    changed = true; 
 | 
                } 
 | 
                else if (!changed) 
 | 
                { 
 | 
                    // Nothing has changed -- we can start here next time 
 | 
                    start = (i == 0) ? 0 : i - 1; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    /// <summary> 
 | 
    /// Comparison function should return -1 if left is less than right, 1 if left is greater than right, and 0 if they match. 
 | 
    /// </summary> 
 | 
  
 | 
    public delegate int CompareFunc (T left, T right); 
 | 
#endif 
 | 
} 
 |