2025-03-14 16:53:25 +08:00
|
|
|
|
#if DISABLE_DEBUG
|
|
|
|
|
#undef DEBUG
|
|
|
|
|
#endif
|
|
|
|
|
using System;
|
2024-12-04 16:09:52 +08:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
|
2025-05-18 10:52:24 +08:00
|
|
|
|
namespace DCFApixels.DragonECS.Core.Internal
|
2024-12-04 16:09:52 +08:00
|
|
|
|
{
|
|
|
|
|
[DebuggerDisplay("Count: {Count}")]
|
|
|
|
|
internal struct StructList<T>
|
|
|
|
|
{
|
2025-07-14 16:20:11 +08:00
|
|
|
|
internal readonly static bool _IsManaged = RuntimeHelpers.IsReferenceOrContainsReferences<T>();
|
|
|
|
|
|
2024-12-04 16:09:52 +08:00
|
|
|
|
internal T[] _items;
|
|
|
|
|
internal int _count;
|
2025-07-14 16:20:11 +08:00
|
|
|
|
|
|
|
|
|
#region Properties
|
2024-12-04 16:09:52 +08:00
|
|
|
|
public int Count
|
|
|
|
|
{
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
get { return _count; }
|
|
|
|
|
}
|
|
|
|
|
public int Capacity
|
|
|
|
|
{
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
get { return _items.Length; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (value <= _items.Length) { return; }
|
2025-03-19 11:18:25 +08:00
|
|
|
|
value = ArrayUtility.NextPow2(value);
|
2024-12-04 16:09:52 +08:00
|
|
|
|
Array.Resize(ref _items, value);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-14 16:20:11 +08:00
|
|
|
|
public bool IsNull
|
|
|
|
|
{
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
get { return _items == null; }
|
|
|
|
|
}
|
2024-12-04 16:09:52 +08:00
|
|
|
|
public T this[int index]
|
|
|
|
|
{
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
|
|
|
|
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
|
|
|
|
|
#endif
|
|
|
|
|
return _items[index];
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
|
|
|
|
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
|
|
|
|
|
#endif
|
|
|
|
|
_items[index] = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-14 16:20:11 +08:00
|
|
|
|
#endregion
|
2024-12-04 16:09:52 +08:00
|
|
|
|
|
2025-07-14 16:20:11 +08:00
|
|
|
|
#region Constructors
|
2024-12-04 16:09:52 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public StructList(int capacity)
|
|
|
|
|
{
|
2025-03-19 11:18:25 +08:00
|
|
|
|
_items = new T[ArrayUtility.NextPow2(capacity)];
|
2024-12-04 16:09:52 +08:00
|
|
|
|
_count = 0;
|
|
|
|
|
}
|
2025-07-14 16:20:11 +08:00
|
|
|
|
#endregion
|
2024-12-04 16:09:52 +08:00
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public void Add(T item)
|
|
|
|
|
{
|
|
|
|
|
if (_count >= _items.Length)
|
|
|
|
|
{
|
|
|
|
|
Array.Resize(ref _items, _items.Length << 1);
|
|
|
|
|
}
|
2025-07-14 16:20:11 +08:00
|
|
|
|
AddFixed(item);
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public void AddFixed(T item)
|
|
|
|
|
{
|
2024-12-04 16:09:52 +08:00
|
|
|
|
_items[_count++] = item;
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public int IndexOf(T item)
|
|
|
|
|
{
|
|
|
|
|
return Array.IndexOf(_items, item, 0, _count);
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2025-07-14 16:20:11 +08:00
|
|
|
|
public bool Contains(T item)
|
|
|
|
|
{
|
|
|
|
|
return _count != 0 && IndexOf(item) >= 0;
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2024-12-04 16:09:52 +08:00
|
|
|
|
public void SwapAt(int idnex1, int idnex2)
|
|
|
|
|
{
|
|
|
|
|
T tmp = _items[idnex1];
|
|
|
|
|
_items[idnex1] = _items[idnex2];
|
|
|
|
|
_items[idnex2] = tmp;
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public void FastRemoveAt(int index)
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
|
|
|
|
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
|
|
|
|
|
#endif
|
|
|
|
|
_items[index] = _items[--_count];
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public void RemoveAt(int index)
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
|
|
|
|
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
|
|
|
|
|
#endif
|
|
|
|
|
_items[index] = _items[--_count];
|
2025-07-14 16:20:11 +08:00
|
|
|
|
if (_IsManaged)
|
|
|
|
|
{
|
|
|
|
|
_items[_count] = default;
|
|
|
|
|
}
|
2024-12-04 16:09:52 +08:00
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public void RemoveAtWithOrder(int index)
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
|
|
|
|
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
|
|
|
|
|
#endif
|
|
|
|
|
for (int i = index; i < _count;)
|
|
|
|
|
{
|
|
|
|
|
_items[i++] = _items[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public bool Remove(T item)
|
|
|
|
|
{
|
|
|
|
|
int index = IndexOf(item);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
{
|
|
|
|
|
RemoveAt(index);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public bool RemoveWithOrder(T item)
|
|
|
|
|
{
|
|
|
|
|
int index = IndexOf(item);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
{
|
|
|
|
|
RemoveAtWithOrder(index);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-07-14 16:20:11 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public T Peek()
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
|
|
|
|
if (_count <= 0) { Throw.EmptyStack(); }
|
|
|
|
|
#endif
|
|
|
|
|
return _items[_count - 1];
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public bool TryPeek(out T result)
|
|
|
|
|
{
|
|
|
|
|
if (_count <= 0)
|
|
|
|
|
{
|
|
|
|
|
result = default;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
result = _items[_count - 1];
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public T Pop()
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
|
|
|
|
if (_count <= 0) { Throw.EmptyStack(); }
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
T result = _items[--_count];
|
|
|
|
|
if (_IsManaged)
|
|
|
|
|
{
|
|
|
|
|
_items[_count] = default;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public bool TryPop(out T result)
|
|
|
|
|
{
|
|
|
|
|
if (_count <= 0)
|
|
|
|
|
{
|
|
|
|
|
result = default;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
result = _items[--_count];
|
|
|
|
|
if (_IsManaged)
|
|
|
|
|
{
|
|
|
|
|
_items[_count] = default;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-04 16:09:52 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public void FastClear()
|
|
|
|
|
{
|
|
|
|
|
_count = 0;
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
2025-07-14 16:20:11 +08:00
|
|
|
|
if (_IsManaged)
|
2024-12-04 16:09:52 +08:00
|
|
|
|
{
|
2025-07-14 16:20:11 +08:00
|
|
|
|
Array.Clear(_items, 0, _count);
|
2024-12-04 16:09:52 +08:00
|
|
|
|
}
|
|
|
|
|
_count = 0;
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2025-07-14 16:20:11 +08:00
|
|
|
|
public void Recreate()
|
|
|
|
|
{
|
|
|
|
|
_items = new T[_items.Length];
|
|
|
|
|
_count = 0;
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public void Recreate(int newSize)
|
|
|
|
|
{
|
|
|
|
|
_items = new T[ArrayUtility.NextPow2(newSize)];
|
|
|
|
|
_count = 0;
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2024-12-04 16:09:52 +08:00
|
|
|
|
public ReadOnlySpan<T>.Enumerator GetEnumerator()
|
|
|
|
|
{
|
|
|
|
|
return new ReadOnlySpan<T>(_items, 0, _count).GetEnumerator();
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2025-07-14 16:20:11 +08:00
|
|
|
|
public ReadOnlySpan<T> AsReadOnlySpan()
|
2024-12-04 16:09:52 +08:00
|
|
|
|
{
|
|
|
|
|
return new ReadOnlySpan<T>(_items, 0, _count);
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public IEnumerable<T> ToEnumerable()
|
|
|
|
|
{
|
|
|
|
|
return _items.Take(_count);
|
|
|
|
|
}
|
2025-07-14 16:20:11 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public T[] ToArray()
|
|
|
|
|
{
|
|
|
|
|
if (_count <= 0) { return Array.Empty<T>(); }
|
|
|
|
|
T[] result = new T[_count];
|
|
|
|
|
Array.Copy(_items, result, _count);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2024-12-04 16:09:52 +08:00
|
|
|
|
}
|
|
|
|
|
}
|