//-------------------------------------------------
// NGUI: Next-Gen UI kit
// Copyright © 2011-2017 Tasharen Entertainment Inc
//-------------------------------------------------
#if !COMBAT_SERVER
using UnityEngine;
#endif
using System;
using System.Collections.Generic;
using System.Diagnostics;
using CombatLibrary.CombatLibrary.CombatCore;
#if !COMBAT_SERVER
using Debug = UnityEngine.Debug;
#endif
///
/// 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.
///
public class BetterList : IDisposable
{
public int tranId;
#if UNITY_FLASH
List mList = new List();
///
/// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size.
///
public T this[int i]
{
get { return mList[i]; }
set { mList[i] = value; }
}
///
/// Compatibility with the non-flash syntax.
///
public List buffer { get { return mList; } }
///
/// Direct access to the buffer's size. Note that it's only public for speed and efficiency. You shouldn't modify it.
///
public int size { get { return mList.Count; } }
///
/// For 'foreach' functionality.
///
public IEnumerator GetEnumerator () { return mList.GetEnumerator(); }
///
/// Clear the array by resetting its size to zero. Note that the memory is not actually released.
///
public void Clear () { mList.Clear(); }
///
/// Clear the array and release the used memory.
///
public void Release () { mList.Clear(); }
///
/// Add the specified item to the end of the list.
///
public void Add (T item) { mList.Add(item); }
///
/// Insert an item at the specified index, pushing the entries back.
///
public void Insert (int index, T item)
{
if (index > -1 && index < mList.Count) mList.Insert(index, item);
else mList.Add(item);
}
///
/// Returns 'true' if the specified item is within the list.
///
public bool Contains (T item) { return mList.Contains(item); }
///
/// Return the index of the specified item.
///
public int IndexOf (T item) { return mList.IndexOf(item); }
///
/// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index.
///
public bool Remove (T item) { return mList.Remove(item); }
///
/// Remove an item at the specified index.
///
public void RemoveAt (int index) { mList.RemoveAt(index); }
///
/// Remove an item from the end.
///
public T Pop ()
{
if (buffer != null && size != 0)
{
T val = buffer[mList.Count - 1];
mList.RemoveAt(mList.Count - 1);
return val;
}
return default(T);
}
///
/// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size.
///
public T[] ToArray () { return mList.ToArray(); }
///
/// List.Sort equivalent.
///
public void Sort (System.Comparison comparer) { mList.Sort(comparer); }
#else
///
/// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size.
///
public T[] buffer;
private int buffSize = 8;
public int Count
{
get { return size; }
}
public bool isNotPool = true;
///
/// Direct access to the buffer's size. Note that it's only public for speed and efficiency. You shouldn't modify it.
///
public int size = 0;
// ///
// /// For 'foreach' functionality.
// ///
// [DebuggerHidden]
// [DebuggerStepThrough]
// public IEnumerator GetEnumerator()
// {
// if (buffer != null)
// {
// for (int i = 0; i < size; ++i)
// {
// yield return buffer[i];
// }
// }
// }
public BetterList()
{
isNotPool = true;
}
// ~BetterList()
// {
// CombatListPool.Instance.Recycle(this);
// }
public BetterList(bool isNotPool)
{
this.isNotPool = isNotPool;
}
public BetterList(bool isNotPool, int size)
{
this.isNotPool = isNotPool;
buffSize = size;
}
public BetterList(int size)
{
buffSize = size;
}
public BetterList(List allVe)
{
buffer = allVe.ToArray();
size = buffer.Length;
}
///
/// Convenience function. I recommend using .buffer instead.
///
[DebuggerHidden]
public T this[int i]
{
get { return buffer[i]; }
set { buffer[i] = value; }
}
///
/// Helper function that expands the size of the array, maintaining the content.
///
void AllocateMore()
{
T[] newList = (buffer != null) ? new T[System.Math.Max(buffer.Length << 1, buffSize)] : new T[buffSize];
if (buffer != null && size > 0) buffer.CopyTo(newList, 0);
buffer = newList;
}
///
/// 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.
///
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;
}
///
/// Clear the array by resetting its size to zero. Note that the memory is not actually released.
///
public void Clear()
{
size = 0;
}
///
/// Clear the array and release the used memory.
///
public void Release()
{
size = 0;
buffer = null;
}
///
/// Add the specified item to the end of the list.
///
public void Add(T item)
{
if (buffer == null || size == buffer.Length) AllocateMore();
buffer[size++] = item;
}
///
/// Insert an item at the specified index, pushing the entries back.
///
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);
}
///
/// Returns 'true' if the specified item is within the list.
///
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;
}
///
/// Return the index of the specified item.
///
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;
}
///
/// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index.
///
public bool Remove(T item)
{
if (buffer != null)
{
EqualityComparer comp = EqualityComparer.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;
}
///
/// Remove an item at the specified index.
///
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);
}
}
///
/// Remove an item from the end.
///
public T Pop()
{
if (buffer != null && size != 0)
{
T val = buffer[--size];
buffer[size] = default(T);
return val;
}
return default(T);
}
public void AddRange(List target)
{
for (int i = 0; i < target.Count; i++)
{
Add(target[i]);
}
}
public void AddRange(T[] target)
{
if (target == null)
{
return;
}
for (int i = 0; i < target.Length; i++)
{
Add(target[i]);
}
}
public void AddRange(BetterList target)
{
for (int i = 0; i < target.Count; i++)
{
Add(target[i]);
}
}
private void Add(object item)
{
if (buffer == null || size == buffer.Length) AllocateMore();
buffer[size++] = (T)item;
}
public void AddRange(BetterList target)
{
// for (int i = 0; i < target.size; i++)
// {
// Add(target[i]);
// }
if (target == null || target.buffer == null)
{
return;
}
if (buffer == null)
{
buffer = new T[0];
}
if (size + target.size > buffer.Length)
{
System.Array.Resize(ref buffer, size + target.size);
}
System.Array.Copy(target.buffer, 0, buffer, size, target.size);
size += target.size;
}
///
/// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size.
///
public T[] ToArray()
{
Trim();
return buffer;
}
//class Comparer : System.Collections.IComparer
//{
// public System.Comparison func;
// public int Compare (object x, object y) { return func((T)x, (T)y); }
//}
//Comparer mComp = new Comparer();
///
/// List.Sort equivalent. Doing Array.Sort causes GC allocations.
///
//public void Sort (System.Comparison comparer)
//{
// if (size > 0)
// {
// mComp.func = comparer;
// System.Array.Sort(buffer, 0, size, mComp);
// }
//}
///
/// List.Sort equivalent. Manual sorting causes no GC allocations.
///
[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;
}
}
}
}
///
/// Comparison function should return -1 if left is less than right, 1 if left is greater than right, and 0 if they match.
///
public delegate int CompareFunc(T left, T right);
#endif
public void Dispose()
{
if (isNotPool)
{
return;
}
CombatListPool.Instance.Recycle(this);
}
}