2025-03-14 16:53:25 +08:00
|
|
|
|
#if DISABLE_DEBUG
|
|
|
|
|
#undef DEBUG
|
|
|
|
|
#endif
|
|
|
|
|
using System;
|
2024-08-26 11:08:13 +08:00
|
|
|
|
using System.Collections.Generic;
|
2024-01-07 18:52:54 +08:00
|
|
|
|
using System.Runtime.CompilerServices;
|
2024-08-31 14:57:42 +08:00
|
|
|
|
#if ENABLE_IL2CPP
|
|
|
|
|
using Unity.IL2CPP.CompilerServices;
|
|
|
|
|
#endif
|
2024-01-07 18:52:54 +08:00
|
|
|
|
|
|
|
|
|
namespace DCFApixels.DragonECS.Internal
|
|
|
|
|
{
|
2024-08-26 11:08:13 +08:00
|
|
|
|
internal interface IStructComparer<T> : IComparer<T>
|
2024-01-07 18:52:54 +08:00
|
|
|
|
{
|
|
|
|
|
// a > b = return > 0
|
2024-08-26 11:08:13 +08:00
|
|
|
|
// int Compare(T a, T b);
|
2024-01-07 18:52:54 +08:00
|
|
|
|
}
|
2024-08-26 11:08:13 +08:00
|
|
|
|
|
2024-08-31 14:57:42 +08:00
|
|
|
|
#if ENABLE_IL2CPP
|
2024-11-08 17:21:36 +08:00
|
|
|
|
[Il2CppSetOption(Option.NullChecks, false)]
|
2024-08-31 14:57:42 +08:00
|
|
|
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
|
|
|
|
#endif
|
2024-01-07 18:52:54 +08:00
|
|
|
|
internal static class ArraySortHalperX<T>
|
|
|
|
|
{
|
|
|
|
|
private const int IntrosortSizeThreshold = 16;
|
|
|
|
|
|
2024-08-26 11:08:13 +08:00
|
|
|
|
#region IStructComparer
|
2024-01-07 18:52:54 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2024-08-23 22:31:43 +08:00
|
|
|
|
public static void SwapIfGreater<TComparer>(T[] items, ref TComparer comparer, int i, int j) where TComparer : IStructComparer<T>
|
2024-01-07 18:52:54 +08:00
|
|
|
|
{
|
|
|
|
|
if (comparer.Compare(items[i], items[j]) > 0)
|
|
|
|
|
{
|
|
|
|
|
T key = items[i];
|
|
|
|
|
items[i] = items[j];
|
|
|
|
|
items[j] = key;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2024-08-23 22:31:43 +08:00
|
|
|
|
public static void InsertionSort<TComparer>(T[] items, ref TComparer comparer) where TComparer : IStructComparer<T>
|
2024-01-07 18:52:54 +08:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < items.Length - 1; i++)
|
|
|
|
|
{
|
|
|
|
|
T t = items[i + 1];
|
|
|
|
|
|
|
|
|
|
int j = i;
|
|
|
|
|
while (j >= 0 && comparer.Compare(t, items[j]) < 0)
|
|
|
|
|
{
|
|
|
|
|
items[j + 1] = items[j];
|
|
|
|
|
j--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
items[j + 1] = t;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-08-26 11:08:13 +08:00
|
|
|
|
|
2024-01-07 18:52:54 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2024-08-23 22:31:43 +08:00
|
|
|
|
public static void Sort<TComparer>(T[] items, ref TComparer comparer) where TComparer : IStructComparer<T>
|
2024-01-07 18:52:54 +08:00
|
|
|
|
{
|
|
|
|
|
int length = items.Length;
|
|
|
|
|
if (length == 1)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (length <= IntrosortSizeThreshold)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (length == 2)
|
|
|
|
|
{
|
|
|
|
|
SwapIfGreater(items, ref comparer, 0, 1);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (length == 3)
|
|
|
|
|
{
|
|
|
|
|
SwapIfGreater(items, ref comparer, 0, 1);
|
|
|
|
|
SwapIfGreater(items, ref comparer, 0, 2);
|
|
|
|
|
SwapIfGreater(items, ref comparer, 1, 2);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InsertionSort(items, ref comparer);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-08-26 11:08:13 +08:00
|
|
|
|
|
2024-08-23 22:31:43 +08:00
|
|
|
|
IStructComparer<T> packed = comparer;
|
2024-08-26 11:08:13 +08:00
|
|
|
|
Array.Sort(items, 0, items.Length, packed);
|
2024-01-07 18:52:54 +08:00
|
|
|
|
comparer = (TComparer)packed;
|
|
|
|
|
}
|
2024-08-26 11:08:13 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Comparison
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public static void SwapIfGreater(T[] items, Comparison<T> comparison, int i, int j)
|
|
|
|
|
{
|
|
|
|
|
if (comparison(items[i], items[j]) > 0)
|
|
|
|
|
{
|
|
|
|
|
T key = items[i];
|
|
|
|
|
items[i] = items[j];
|
|
|
|
|
items[j] = key;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public static void InsertionSort(T[] items, int length, Comparison<T> comparison)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < length - 1; i++)
|
|
|
|
|
{
|
|
|
|
|
T t = items[i + 1];
|
|
|
|
|
|
|
|
|
|
int j = i;
|
|
|
|
|
while (j >= 0 && comparison(t, items[j]) < 0)
|
|
|
|
|
{
|
|
|
|
|
items[j + 1] = items[j];
|
|
|
|
|
j--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
items[j + 1] = t;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-31 14:57:42 +08:00
|
|
|
|
#if ENABLE_IL2CPP
|
2024-11-08 17:21:36 +08:00
|
|
|
|
[Il2CppSetOption(Option.NullChecks, false)]
|
2024-08-31 14:57:42 +08:00
|
|
|
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
|
|
|
|
#endif
|
2024-08-26 11:08:13 +08:00
|
|
|
|
private class ComparisonHach : IComparer<T>
|
|
|
|
|
{
|
|
|
|
|
public static readonly ComparisonHach Instance = new ComparisonHach();
|
|
|
|
|
public Comparison<T> comparison;
|
|
|
|
|
private ComparisonHach() { }
|
|
|
|
|
public int Compare(T x, T y) { return comparison(x, y); }
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public static void Sort(T[] items, Comparison<T> comparison)
|
|
|
|
|
{
|
|
|
|
|
Sort(items, comparison, items.Length);
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public static void Sort(T[] items, Comparison<T> comparison, int length)
|
|
|
|
|
{
|
|
|
|
|
if (length <= IntrosortSizeThreshold)
|
|
|
|
|
{
|
|
|
|
|
if (length == 1)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (length == 2)
|
|
|
|
|
{
|
|
|
|
|
SwapIfGreater(items, comparison, 0, 1);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (length == 3)
|
|
|
|
|
{
|
|
|
|
|
SwapIfGreater(items, comparison, 0, 1);
|
|
|
|
|
SwapIfGreater(items, comparison, 0, 2);
|
|
|
|
|
SwapIfGreater(items, comparison, 1, 2);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
InsertionSort(items, length, comparison);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ComparisonHach.Instance.comparison = comparison;
|
|
|
|
|
Array.Sort(items, 0, length, ComparisonHach.Instance);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
2024-01-07 18:52:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-08-31 14:57:42 +08:00
|
|
|
|
#if ENABLE_IL2CPP
|
2024-11-08 17:21:36 +08:00
|
|
|
|
[Il2CppSetOption(Option.NullChecks, false)]
|
2024-08-31 14:57:42 +08:00
|
|
|
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
|
|
|
|
#endif
|
2024-01-07 18:52:54 +08:00
|
|
|
|
internal static unsafe class UnsafeArraySortHalperX<T> where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
private const int IntrosortSizeThreshold = 16;
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2024-08-23 22:31:43 +08:00
|
|
|
|
public static void SwapIfGreater<TComparer>(T* items, ref TComparer comparer, int i, int j) where TComparer : IStructComparer<T>
|
2024-01-07 18:52:54 +08:00
|
|
|
|
{
|
|
|
|
|
if (comparer.Compare(items[i], items[j]) > 0)
|
|
|
|
|
{
|
|
|
|
|
T key = items[i];
|
|
|
|
|
items[i] = items[j];
|
|
|
|
|
items[j] = key;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2024-08-23 22:31:43 +08:00
|
|
|
|
public static void InsertionSort_Unchecked<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IStructComparer<T>
|
2024-01-07 18:52:54 +08:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < length - 1; i++)
|
|
|
|
|
{
|
|
|
|
|
T t = items[i + 1];
|
|
|
|
|
|
|
|
|
|
int j = i;
|
|
|
|
|
while (j >= 0 && comparer.Compare(t, items[j]) < 0)
|
|
|
|
|
{
|
|
|
|
|
items[j + 1] = items[j];
|
|
|
|
|
j--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
items[j + 1] = t;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
//public static void OptimizedBubbleSort_Unchecked<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IComparerX<T>
|
|
|
|
|
//{
|
|
|
|
|
// for (int i = 0, n = length - 1; i < n; i++)
|
|
|
|
|
// {
|
|
|
|
|
// bool noSwaped = true;
|
|
|
|
|
// for (int j = 0; j < n - i;)
|
|
|
|
|
// {
|
|
|
|
|
// ref T j0 = ref items[j++];
|
|
|
|
|
// if(comparer.Compare(j0, items[j]) < 0)
|
|
|
|
|
// {
|
|
|
|
|
// T tmp = items[j];
|
|
|
|
|
// items[j] = j0;
|
|
|
|
|
// j0 = tmp;
|
|
|
|
|
// noSwaped = false;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// if (noSwaped)
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
//}
|
2024-08-23 22:31:43 +08:00
|
|
|
|
public static void InsertionSort<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IStructComparer<T>
|
2024-01-07 18:52:54 +08:00
|
|
|
|
{
|
|
|
|
|
if (length == 1)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (length == 2)
|
|
|
|
|
{
|
|
|
|
|
SwapIfGreater(items, ref comparer, 0, 1);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (length == 3)
|
|
|
|
|
{
|
|
|
|
|
SwapIfGreater(items, ref comparer, 0, 1);
|
|
|
|
|
SwapIfGreater(items, ref comparer, 0, 2);
|
|
|
|
|
SwapIfGreater(items, ref comparer, 1, 2);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InsertionSort_Unchecked(items, length, ref comparer);
|
|
|
|
|
}
|
|
|
|
|
//public static void OptimizedBubbleSort<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IComparerX<T>
|
|
|
|
|
//{
|
|
|
|
|
// if (length == 1)
|
|
|
|
|
// {
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (length == 2)
|
|
|
|
|
// {
|
|
|
|
|
// SwapIfGreater(items, ref comparer, 0, 1);
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (length == 3)
|
|
|
|
|
// {
|
|
|
|
|
// SwapIfGreater(items, ref comparer, 0, 1);
|
|
|
|
|
// SwapIfGreater(items, ref comparer, 0, 2);
|
|
|
|
|
// SwapIfGreater(items, ref comparer, 1, 2);
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// OptimizedBubbleSort_Unchecked(items, length, ref comparer);
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|