Files
EnglewoodLAB/Assets/Scripts/UVC/Pool/SmallList.cs

224 lines
6.9 KiB
C#

using UnityEngine;
namespace UVC.Pool
{
/// <summary>
/// List와 유사하게 작동하는 경량 배열 구현입니다.
/// 필요할 때 자동으로 메모리를 할당하지만, 가비지 컬렉션을 위해 메모리를 해제하지는 않습니다.
/// 이는 특히 게임 개발과 같이 성능이 중요한 상황에서 가비지 컬렉션으로 인한 멈춤 현상을 방지하는 데 유용합니다.
///
/// 사용 예:
/// <code>
/// SmallList<int> numbers = new SmallList<int>();
/// numbers.AddChild(10);
/// numbers.AddChild(20);
/// int firstNumber = numbers[0]; // 10
/// </code>
/// </summary>
/// <typeparam name="T">리스트에 저장할 요소의 타입입니다.</typeparam>
public class SmallList<T>
{
/// <summary>
/// 리스트 데이터를 저장하는 내부 배열입니다.
/// </summary>
public T[] data;
/// <summary>
/// 리스트에 있는 요소의 수입니다.
/// </summary>
public int Count = 0;
/// <summary>
/// 인덱스를 통해 리스트 항목에 접근합니다.
/// </summary>
/// <param name="i">접근할 요소의 인덱스입니다.</param>
/// <returns>지정된 인덱스의 요소입니다.</returns>
public T this[int i]
{
get { return data[i]; }
set { data[i] = value; }
}
/// <summary>
/// 더 많은 메모리가 필요할 때 배열의 크기를 조정합니다.
/// </summary>
private void ResizeArray()
{
T[] newData;
if (data != null)
newData = new T[Mathf.Max(data.Length << 1, 64)];
else
newData = new T[64];
if (data != null && Count > 0)
data.CopyTo(newData, 0);
data = newData;
}
/// <summary>
/// 가비지 컬렉션에 메모리를 해제하는 대신 리스트 크기를 0으로 재설정하여 모든 요소를 지웁니다.
/// </summary>
public void Clear()
{
Count = 0;
}
/// <summary>
/// 리스트의 첫 번째 요소를 반환합니다.
/// </summary>
/// <returns>리스트의 첫 번째 요소입니다. 리스트가 비어 있으면 default(T)를 반환합니다.</returns>
public T First()
{
if (data == null || Count == 0) return default(T);
return data[0];
}
/// <summary>
/// 리스트의 마지막 요소를 반환합니다.
/// </summary>
/// <returns>리스트의 마지막 요소입니다. 리스트가 비어 있으면 default(T)를 반환합니다.</returns>
public T Last()
{
if (data == null || Count == 0) return default(T);
return data[Count - 1];
}
/// <summary>
/// 배열 끝에 새 요소를 추가하고 필요한 경우 메모리를 더 할당합니다.
/// </summary>
/// <param name="item">추가할 요소입니다.</param>
public void Add(T item)
{
if (data == null || Count == data.Length)
ResizeArray();
data[Count] = item;
Count++;
}
/// <summary>
/// 배열 시작 부분에 새 요소를 추가하고 필요한 경우 메모리를 더 할당합니다.
/// </summary>
/// <param name="item">추가할 요소입니다.</param>
public void AddStart(T item)
{
Insert(item, 0);
}
/// <summary>
/// 지정된 인덱스에 새 요소를 삽입하고 필요한 경우 메모리를 더 할당합니다.
/// </summary>
/// <param name="item">삽입할 요소입니다.</param>
/// <param name="index">요소를 삽입할 인덱스입니다.</param>
public void Insert(T item, int index)
{
if (data == null || Count == data.Length)
ResizeArray();
for (var i = Count; i > index; i--)
{
data[i] = data[i - 1];
}
data[index] = item;
Count++;
}
/// <summary>
/// 데이터 시작 부분에서 항목을 제거합니다.
/// </summary>
/// <returns>제거된 요소입니다.</returns>
public T RemoveStart()
{
return RemoveAt(0);
}
/// <summary>
/// 지정된 인덱스에서 항목을 제거합니다.
/// </summary>
/// <param name="index">제거할 요소의 인덱스입니다.</param>
/// <returns>제거된 요소입니다.</returns>
public T RemoveAt(int index)
{
if (data != null && Count != 0)
{
T val = data[index];
for (var i = index; i < Count - 1; i++)
{
data[i] = data[i + 1];
}
Count--;
data[Count] = default(T);
return val;
}
else
{
return default(T);
}
}
/// <summary>
/// 데이터에서 특정 항목을 제거합니다.
/// </summary>
/// <param name="item">제거할 요소입니다.</param>
/// <returns>제거된 요소입니다. 항목을 찾지 못하면 default(T)를 반환합니다.</returns>
public T Remove(T item)
{
if (data != null && Count != 0)
{
for (var i = 0; i < Count; i++)
{
if (data[i].Equals(item))
{
return RemoveAt(i);
}
}
}
return default(T);
}
/// <summary>
/// 데이터 끝에서 항목을 제거합니다.
/// </summary>
/// <returns>제거된 요소입니다.</returns>
public T RemoveEnd()
{
if (data != null && Count != 0)
{
Count--;
T val = data[Count];
data[Count] = default(T);
return val;
}
else
{
return default(T);
}
}
/// <summary>
/// 데이터에 특정 항목이 포함되어 있는지 확인합니다.
/// </summary>
/// <param name="item">비교할 항목입니다.</param>
/// <returns>항목이 데이터에 있으면 true, 그렇지 않으면 false를 반환합니다.</returns>
public bool Contains(T item)
{
if (data == null)
return false;
for (var i = 0; i < Count; i++)
{
if (data[i].Equals(item))
return true;
}
return false;
}
}
}