mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2026-04-22 01:45:55 +08:00
update sorting
This commit is contained in:
parent
01985d7ffb
commit
ee65362a1b
@ -5,7 +5,6 @@ using DCFApixels.DragonECS.Core;
|
|||||||
using DCFApixels.DragonECS.Core.Internal;
|
using DCFApixels.DragonECS.Core.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@ -644,7 +643,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
if (_sortIncChunckBuffer.Length > 1)
|
if (_sortIncChunckBuffer.Length > 1)
|
||||||
{
|
{
|
||||||
sortIncBuffer.AsSpan().Sort(new IncCountComparer(counts));
|
ArraySortUtility.Sort(sortIncBuffer.AsSpan(), new IncCountComparer(counts));
|
||||||
ConvertToChuncks(preSortingBuffer, sortIncBuffer, _sortIncChunckBuffer);
|
ConvertToChuncks(preSortingBuffer, sortIncBuffer, _sortIncChunckBuffer);
|
||||||
}
|
}
|
||||||
if (_sortIncChunckBuffer.Length > 0)
|
if (_sortIncChunckBuffer.Length > 0)
|
||||||
@ -658,7 +657,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
if (_sortExcChunckBuffer.Length > 1)
|
if (_sortExcChunckBuffer.Length > 1)
|
||||||
{
|
{
|
||||||
sortExcBuffer.AsSpan().Sort(new ExcCountComparer(counts));
|
ArraySortUtility.Sort(sortExcBuffer.AsSpan(), new ExcCountComparer(counts));
|
||||||
ConvertToChuncks(preSortingBuffer, sortExcBuffer, _sortExcChunckBuffer);
|
ConvertToChuncks(preSortingBuffer, sortExcBuffer, _sortExcChunckBuffer);
|
||||||
}
|
}
|
||||||
// Выражение IncCount < (AllEntitesCount - ExcCount) мало вероятно будет истинным.
|
// Выражение IncCount < (AllEntitesCount - ExcCount) мало вероятно будет истинным.
|
||||||
@ -668,7 +667,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
if (_sortAnyChunckBuffer.Length > 1)
|
if (_sortAnyChunckBuffer.Length > 1)
|
||||||
{
|
{
|
||||||
sortAnyBuffer.AsSpan().Sort(new ExcCountComparer(counts));
|
ArraySortUtility.Sort(sortAnyBuffer.AsSpan(), new ExcCountComparer(counts));
|
||||||
ConvertToChuncks(preSortingBuffer, sortAnyBuffer, _sortAnyChunckBuffer);
|
ConvertToChuncks(preSortingBuffer, sortAnyBuffer, _sortAnyChunckBuffer);
|
||||||
}
|
}
|
||||||
// Any не влияет на maxEntites если есть Inc и сложно высчитывается если нет Inc
|
// Any не влияет на maxEntites если есть Inc и сложно высчитывается если нет Inc
|
||||||
|
|||||||
@ -146,8 +146,7 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
public EcsUnsafeSpan Execute(Comparison<int> comparison)
|
public EcsUnsafeSpan Execute(Comparison<int> comparison)
|
||||||
{
|
{
|
||||||
Execute_Iternal();
|
Execute_Iternal();
|
||||||
Span<int> result = _filteredAllEntities.AsSpan(_filteredAllEntitiesCount);
|
ArraySortUtility.Sort(_filteredAllEntities.AsSpan(_filteredAllEntitiesCount), comparison);
|
||||||
result.Sort(comparison);
|
|
||||||
return new EcsUnsafeSpan(World.ID, _filteredAllEntities.Ptr, _filteredAllEntitiesCount);
|
return new EcsUnsafeSpan(World.ID, _filteredAllEntities.Ptr, _filteredAllEntitiesCount);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -158,8 +157,7 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
return Execute(comparison);
|
return Execute(comparison);
|
||||||
}
|
}
|
||||||
ExecuteFor_Iternal(source);
|
ExecuteFor_Iternal(source);
|
||||||
Span<int> result = _filteredEntities.AsSpan(_filteredEntitiesCount);
|
ArraySortUtility.Sort(_filteredEntities.AsSpan(_filteredEntitiesCount), comparison);
|
||||||
result.Sort(comparison);
|
|
||||||
return new EcsUnsafeSpan(World.ID, _filteredEntities.Ptr, _filteredEntitiesCount);
|
return new EcsUnsafeSpan(World.ID, _filteredEntities.Ptr, _filteredEntitiesCount);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -180,6 +180,11 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
{
|
{
|
||||||
return From<T>(new ReadOnlySpan<T>(ptr, length));
|
return From<T>(new ReadOnlySpan<T>(ptr, length));
|
||||||
}
|
}
|
||||||
|
public static HMem<T> From<T>(T[] source)
|
||||||
|
where T : unmanaged
|
||||||
|
{
|
||||||
|
return From(new ReadOnlySpan<T>(source));
|
||||||
|
}
|
||||||
public static HMem<T> From<T>(ReadOnlySpan<T> source)
|
public static HMem<T> From<T>(ReadOnlySpan<T> source)
|
||||||
where T : unmanaged
|
where T : unmanaged
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Numerics;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
using Unity.IL2CPP.CompilerServices;
|
using Unity.IL2CPP.CompilerServices;
|
||||||
@ -16,17 +15,89 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
[Il2CppSetOption(Option.NullChecks, false)]
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
#endif
|
#endif
|
||||||
internal static class ArraySortUtility
|
internal static unsafe class ArraySortUtility
|
||||||
{
|
{
|
||||||
internal static StructComparison<T> ToStruct<T>(this Comparison<T> self)
|
internal static StructComparison<T> ToStruct<T>(this Comparison<T> self)
|
||||||
{
|
{
|
||||||
return new StructComparison<T>(self);
|
return new StructComparison<T>(self);
|
||||||
}
|
}
|
||||||
|
internal static StructComparer<T> ToStruct<T>(this Comparer<T> self)
|
||||||
|
{
|
||||||
|
return new StructComparer<T>(self);
|
||||||
|
}
|
||||||
|
public static void Sort<T>(Span<T> span)
|
||||||
|
{
|
||||||
|
var c = Comparer<T>.Default.ToStruct();
|
||||||
|
ArraySortUtility<T, StructComparer<T>>.Sort(span, ref c);
|
||||||
|
}
|
||||||
|
public static void Sort<T>(Span<T> span, Comparer<T> comparer)
|
||||||
|
{
|
||||||
|
var c = comparer.ToStruct();
|
||||||
|
ArraySortUtility<T, StructComparer<T>>.Sort(span, ref c);
|
||||||
|
}
|
||||||
public static void Sort<T>(Span<T> span, Comparison<T> comparison)
|
public static void Sort<T>(Span<T> span, Comparison<T> comparison)
|
||||||
{
|
{
|
||||||
var c = comparison.ToStruct();
|
var c = comparison.ToStruct();
|
||||||
ArraySortUtility<T, StructComparison<T>>.Sort(span, ref c);
|
ArraySortUtility<T, StructComparison<T>>.Sort(span, ref c);
|
||||||
}
|
}
|
||||||
|
public static void Sort<T, TComparer>(Span<T> span, ref TComparer comparer)
|
||||||
|
where TComparer : struct, IComparer<T>
|
||||||
|
{
|
||||||
|
ArraySortUtility<T, TComparer>.Sort(span, ref comparer);
|
||||||
|
}
|
||||||
|
public static void Sort<T, TComparer>(Span<T> span, TComparer comparer)
|
||||||
|
where TComparer : struct, IComparer<T>
|
||||||
|
{
|
||||||
|
ArraySortUtility<T, TComparer>.Sort(span, ref comparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Таблица для De Bruijn-умножения (позиция старшего бита для чисел 0..31)
|
||||||
|
private const int Log2DeBruijn32_Length = 32;
|
||||||
|
private static readonly uint* Log2DeBruijn32 = MemoryAllocator.From(new uint[Log2DeBruijn32_Length]
|
||||||
|
{
|
||||||
|
0, 9, 1, 10, 13, 21, 2, 29, 11, 14,
|
||||||
|
16, 18, 22, 25, 3, 30, 8, 12, 20, 28,
|
||||||
|
15, 17, 24, 7, 19, 27, 23, 6, 26, 5,
|
||||||
|
4, 31
|
||||||
|
//0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
||||||
|
//8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
|
||||||
|
}).Ptr;
|
||||||
|
|
||||||
|
/// <summary>32-битный логарифм по основанию 2 (округление вниз). Для value = 0 возвращает 0.</summary>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static int Log2(uint value)
|
||||||
|
{
|
||||||
|
// Для нуля сразу возвращаем 0 (по договорённости, чтобы избежать исключения)
|
||||||
|
if (value == 0) return 0;
|
||||||
|
|
||||||
|
// Заполняем все биты справа от старшего единицей: превращаем число в 2^n - 1
|
||||||
|
value |= value >> 1;
|
||||||
|
value |= value >> 2;
|
||||||
|
value |= value >> 4;
|
||||||
|
value |= value >> 8;
|
||||||
|
value |= value >> 16;
|
||||||
|
|
||||||
|
// Умножение на константу De Bruijn и сдвиг для получения индекса в таблице
|
||||||
|
return (int)Log2DeBruijn32[(value * 0x07C4ACDDu) >> 27];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>64-битный логарифм по основанию 2 (округление вниз). Для value = 0 возвращает 0.</summary>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static int Log2(ulong value)
|
||||||
|
{
|
||||||
|
if (value == 0) { return 0; }
|
||||||
|
|
||||||
|
uint high = (uint)(value >> 32);
|
||||||
|
if (high == 0)
|
||||||
|
{
|
||||||
|
return Log2((uint)value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 32 + Log2(high);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
[Il2CppSetOption(Option.NullChecks, false)]
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
@ -44,6 +115,18 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
return Comparison(x, y);
|
return Comparison(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
internal readonly struct StructComparer<T> : IComparer<T>
|
||||||
|
{
|
||||||
|
public readonly Comparer<T> Comparer;
|
||||||
|
public StructComparer(Comparer<T> comparer)
|
||||||
|
{
|
||||||
|
Comparer = comparer;
|
||||||
|
}
|
||||||
|
public int Compare(T x, T y)
|
||||||
|
{
|
||||||
|
return Comparer.Compare(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
// a > b = return > 0
|
// a > b = return > 0
|
||||||
// int Compare(T a, T b);
|
// int Compare(T a, T b);
|
||||||
|
|
||||||
@ -126,7 +209,7 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
//Debug.Assert(comparer != null);
|
//Debug.Assert(comparer != null);
|
||||||
if (keys.Length > 1)
|
if (keys.Length > 1)
|
||||||
{
|
{
|
||||||
IntroSort(keys, 2 * (BitOperations.Log2((uint)keys.Length) + 1), ref comparer);
|
IntroSort(keys, 2 * (ArraySortUtility.Log2((uint)keys.Length) + 1), ref comparer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: a591de1858028504d819333121bfddd6
|
guid: fe9273da3e82bfd48983415b1726aed1
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
Loading…
Reference in New Issue
Block a user