123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- //----------------------------------------------
- // 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.
- /// PRO: BetterList performs faster than List when you Add and Remove items (although slower if you remove from the beginning).
- /// CON: BetterList performs worse when sorting the list. If your operations involve sorting, use the standard List instead.
- /// </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)
- {
- if (index > -1 && index < mList.Count) mList.Insert(index, item);
- else mList.Add(item);
- }
- /// <summary>
- /// Returns 'true' if the specified item is within the list.
- /// </summary>
- public bool Contains (T item) { return mList.Contains(item); }
- /// <summary>
- /// Return the index of the specified item.
- /// </summary>
- public int IndexOf (T item) { return mList.IndexOf(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 > -1 && 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>
- /// Return the index of the specified item.
- /// </summary>
- public int IndexOf(T item)
- {
- if (buffer == null) return -1;
- for (int i = 0; i < size; ++i) if (buffer[i].Equals(item)) return i;
- return -1;
- }
- /// <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 > -1 && 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
- }
|