259 lines
6.1 KiB
C#
259 lines
6.1 KiB
C#
//----------------------------------------------
|
|
// NGUI: Next-Gen UI kit
|
|
// Copyright © 2011-2015 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 ObjDisOrderList<T> where T : Object
|
|
{
|
|
/// <summary>
|
|
/// 索引改变回调函数
|
|
/// </summary>
|
|
private IndexChangeFunc _indexChangeFunc;
|
|
|
|
/// <summary>
|
|
/// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size.
|
|
/// </summary>
|
|
|
|
private T[] _buffer;
|
|
public T[] buffer
|
|
{
|
|
get
|
|
{
|
|
return _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;
|
|
|
|
public ObjDisOrderList()
|
|
{
|
|
|
|
}
|
|
|
|
public ObjDisOrderList(int capacity)
|
|
{
|
|
_buffer = new T[capacity];
|
|
}
|
|
|
|
/// <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
|
|
{
|
|
var oldValue = _buffer[i];
|
|
if(oldValue != value)
|
|
{
|
|
_buffer[i] = value;
|
|
//移除老的
|
|
DoIndexChanged(oldValue, -1);
|
|
//添加新的
|
|
DoIndexChanged(value, i);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <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;
|
|
//添加新的
|
|
DoIndexChanged(item, size);
|
|
++size;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns 'true' if the specified item is within the list.
|
|
/// </summary>
|
|
|
|
public bool Contains (T item)
|
|
{
|
|
if (_buffer == null) return false;
|
|
var hashCode = item.GetHashCode();
|
|
for (int i = 0; i < size; ++i)
|
|
{
|
|
if (_buffer[i].GetHashCode() == hashCode)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return the index of the specified item.
|
|
/// </summary>
|
|
|
|
public int IndexOf (T item)
|
|
{
|
|
if (_buffer == null) return -1;
|
|
var hashCode = item.GetHashCode();
|
|
for (int i = 0; i < size; ++i)
|
|
{
|
|
if (_buffer[i].GetHashCode() == hashCode)
|
|
{
|
|
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 && item != null)
|
|
{
|
|
var hashCode = item.GetHashCode();
|
|
for (int i = 0; i < size; ++i)
|
|
{
|
|
if (_buffer[i].GetHashCode() == hashCode)
|
|
{
|
|
--size;
|
|
DoIndexChanged(_buffer[i], -1);
|
|
//将最后一个元素放入此位置
|
|
_buffer[i] = _buffer[size];
|
|
DoIndexChanged(_buffer[i], i);
|
|
_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;
|
|
DoIndexChanged(_buffer[index], -1);
|
|
//将最后一个元素放入此位置
|
|
_buffer[index] = _buffer[size];
|
|
DoIndexChanged(_buffer[index], index);
|
|
_buffer[size] = 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; }
|
|
|
|
/// <summary>
|
|
/// 索引改变回调函数
|
|
/// </summary>
|
|
public void SetIndexChangeFunc(IndexChangeFunc func)
|
|
{
|
|
_indexChangeFunc = func;
|
|
}
|
|
|
|
private void DoIndexChanged(T item, int index)
|
|
{
|
|
if(_indexChangeFunc != null)
|
|
{
|
|
_indexChangeFunc(item, index);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 索引改变回调
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="index"></param>
|
|
public delegate void IndexChangeFunc (T item, int index);
|
|
}
|