mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-09-27 02:36:14 +00:00
提交Unity 联机Pro
This commit is contained in:
346
JNFrame2/Assets/Plugins/SRF/Scripts/Collections/SRList.cs
Normal file
346
JNFrame2/Assets/Plugins/SRF/Scripts/Collections/SRList.cs
Normal file
@@ -0,0 +1,346 @@
|
||||
namespace SRF
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// IList implementation which does not release the buffer when clearing/removing elements. Based on the NGUI BetterList
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SRList<T> : IList<T>, ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField] private T[] _buffer;
|
||||
[SerializeField] private int _count;
|
||||
private EqualityComparer<T> _equalityComparer;
|
||||
private ReadOnlyCollection<T> _readOnlyWrapper;
|
||||
public SRList() {}
|
||||
|
||||
public SRList(int capacity)
|
||||
{
|
||||
Buffer = new T[capacity];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new list with the range of values. Contains a foreach loop, which will allocate garbage when used with most
|
||||
/// generic collection types.
|
||||
/// </summary>
|
||||
public SRList(IEnumerable<T> source)
|
||||
{
|
||||
AddRange(source);
|
||||
}
|
||||
|
||||
public T[] Buffer
|
||||
{
|
||||
get { return _buffer; }
|
||||
private set { _buffer = value; }
|
||||
}
|
||||
|
||||
private EqualityComparer<T> EqualityComparer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_equalityComparer == null)
|
||||
{
|
||||
_equalityComparer = EqualityComparer<T>.Default;
|
||||
}
|
||||
|
||||
return _equalityComparer;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _count; }
|
||||
private set { _count = value; }
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
if (Buffer != null)
|
||||
{
|
||||
for (var i = 0; i < Count; ++i)
|
||||
{
|
||||
yield return Buffer[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
if (Buffer == null || Count == Buffer.Length)
|
||||
{
|
||||
Expand();
|
||||
}
|
||||
|
||||
Buffer[Count++] = item;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < Count; ++i)
|
||||
{
|
||||
if (EqualityComparer.Equals(Buffer[i], item))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
Trim();
|
||||
Buffer.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var index = IndexOf(item);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RemoveAt(index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public int IndexOf(T item)
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (var i = 0; i < Count; ++i)
|
||||
{
|
||||
if (EqualityComparer.Equals(Buffer[i], item))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
if (Buffer == null || Count == Buffer.Length)
|
||||
{
|
||||
Expand();
|
||||
}
|
||||
|
||||
if (index < Count)
|
||||
{
|
||||
for (var i = Count; i > index; --i)
|
||||
{
|
||||
Buffer[i] = Buffer[i - 1];
|
||||
}
|
||||
Buffer[index] = item;
|
||||
++Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
if (Buffer != null && index < Count)
|
||||
{
|
||||
--Count;
|
||||
Buffer[index] = default(T);
|
||||
for (var b = index; b < Count; ++b)
|
||||
{
|
||||
Buffer[b] = Buffer[b + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
return Buffer[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
Buffer[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
// Clean buffer of unused elements before serializing
|
||||
Clean();
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add range of values to the list. Contains a foreach loop, which will allocate garbage when used with most
|
||||
/// generic collection types.
|
||||
/// </summary>
|
||||
/// <param name="range"></param>
|
||||
public void AddRange(IEnumerable<T> range)
|
||||
{
|
||||
foreach (var item in range)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the list, optionally setting each element to default(T)
|
||||
/// </summary>
|
||||
public void Clear(bool clean)
|
||||
{
|
||||
Clear();
|
||||
|
||||
if (!clean)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Clean();
|
||||
}
|
||||
|
||||
public void Clean()
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = Count; i < _buffer.Length; i++)
|
||||
{
|
||||
_buffer[i] = default(T);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a read-only wrapper of this list. This is cached, so very little cost after first called.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ReadOnlyCollection<T> AsReadOnly()
|
||||
{
|
||||
if (_readOnlyWrapper == null)
|
||||
{
|
||||
_readOnlyWrapper = new ReadOnlyCollection<T>(this);
|
||||
}
|
||||
|
||||
return _readOnlyWrapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function that expands the size of the array, maintaining the content.
|
||||
/// </summary>
|
||||
private void Expand()
|
||||
{
|
||||
var newList = (Buffer != null) ? new T[Mathf.Max(Buffer.Length << 1, 32)] : new T[32];
|
||||
|
||||
if (Buffer != null && Count > 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>
|
||||
public void Trim()
|
||||
{
|
||||
if (Count > 0)
|
||||
{
|
||||
if (Count >= Buffer.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var newList = new T[Count];
|
||||
|
||||
for (var i = 0; i < Count; ++i)
|
||||
{
|
||||
newList[i] = Buffer[i];
|
||||
}
|
||||
|
||||
Buffer = newList;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer = new T[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List.Sort equivalent.
|
||||
/// </summary>
|
||||
public void Sort(Comparison<T> comparer)
|
||||
{
|
||||
var changed = true;
|
||||
|
||||
while (changed)
|
||||
{
|
||||
changed = false;
|
||||
|
||||
for (var i = 1; i < Count; ++i)
|
||||
{
|
||||
if (comparer.Invoke(Buffer[i - 1], Buffer[i]) > 0)
|
||||
{
|
||||
var temp = Buffer[i];
|
||||
Buffer[i] = Buffer[i - 1];
|
||||
Buffer[i - 1] = temp;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5201015973137a64986d1c3a21aa95bd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
Reference in New Issue
Block a user