2024-01-05 23:49:29 +08:00
|
|
|
|
using System;
|
2024-01-07 18:52:54 +08:00
|
|
|
|
using System.Collections;
|
2024-01-05 23:49:29 +08:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Runtime.CompilerServices;
|
2023-12-24 18:11:20 +08:00
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
2024-02-07 22:16:41 +08:00
|
|
|
|
namespace DCFApixels.DragonECS.Internal
|
2023-04-08 00:47:35 +08:00
|
|
|
|
{
|
|
|
|
|
internal static class ArrayUtility
|
|
|
|
|
{
|
2024-02-07 22:16:41 +08:00
|
|
|
|
private static int GetHighBitNumber(uint bits)
|
|
|
|
|
{
|
|
|
|
|
if (bits == 0)
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
int bit = 0;
|
|
|
|
|
if ((bits & 0xFFFF0000) != 0)
|
|
|
|
|
{
|
|
|
|
|
bits >>= 16;
|
|
|
|
|
bit |= 16;
|
|
|
|
|
}
|
|
|
|
|
if ((bits & 0xFF00) != 0)
|
|
|
|
|
{
|
|
|
|
|
bits >>= 8;
|
|
|
|
|
bit |= 8;
|
|
|
|
|
}
|
|
|
|
|
if ((bits & 0xF0) != 0)
|
|
|
|
|
{
|
|
|
|
|
bits >>= 4;
|
|
|
|
|
bit |= 4;
|
|
|
|
|
}
|
|
|
|
|
if ((bits & 0xC) != 0)
|
|
|
|
|
{
|
|
|
|
|
bits >>= 2;
|
|
|
|
|
bit |= 2;
|
|
|
|
|
}
|
|
|
|
|
if ((bits & 0x2) != 0)
|
|
|
|
|
{
|
|
|
|
|
bit |= 1;
|
|
|
|
|
}
|
|
|
|
|
return bit;
|
|
|
|
|
}
|
|
|
|
|
public static int NormalizeSizeToPowerOfTwo(int minSize)
|
|
|
|
|
{
|
2024-02-13 21:00:01 +08:00
|
|
|
|
unchecked
|
|
|
|
|
{
|
|
|
|
|
return 1 << (GetHighBitNumber((uint)minSize - 1u) + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public static int NormalizeSizeToPowerOfTwo_ClampOverflow(int minSize)
|
|
|
|
|
{
|
|
|
|
|
unchecked
|
|
|
|
|
{
|
|
|
|
|
int hibit = (GetHighBitNumber((uint)minSize - 1u) + 1);
|
|
|
|
|
if (hibit >= 32)
|
|
|
|
|
{
|
|
|
|
|
return int.MaxValue;
|
|
|
|
|
}
|
|
|
|
|
return 1 << hibit;
|
|
|
|
|
}
|
2024-02-07 22:16:41 +08:00
|
|
|
|
}
|
2023-04-08 00:47:35 +08:00
|
|
|
|
public static void Fill<T>(T[] array, T value, int startIndex = 0, int length = -1)
|
|
|
|
|
{
|
|
|
|
|
if (length < 0)
|
2024-02-07 22:16:41 +08:00
|
|
|
|
{
|
2023-04-08 00:47:35 +08:00
|
|
|
|
length = array.Length;
|
2024-02-07 22:16:41 +08:00
|
|
|
|
}
|
2023-04-08 00:47:35 +08:00
|
|
|
|
else
|
2024-02-07 22:16:41 +08:00
|
|
|
|
{
|
2023-04-08 00:47:35 +08:00
|
|
|
|
length = startIndex + length;
|
2024-02-07 22:16:41 +08:00
|
|
|
|
}
|
2023-04-08 00:47:35 +08:00
|
|
|
|
for (int i = startIndex; i < length; i++)
|
2024-02-07 22:16:41 +08:00
|
|
|
|
{
|
2023-04-08 00:47:35 +08:00
|
|
|
|
array[i] = value;
|
2024-02-07 22:16:41 +08:00
|
|
|
|
}
|
2023-04-08 00:47:35 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-01-07 18:52:54 +08:00
|
|
|
|
internal readonly struct EnumerableInt : IEnumerable<int>
|
|
|
|
|
{
|
|
|
|
|
public readonly int start;
|
|
|
|
|
public readonly int length;
|
|
|
|
|
private EnumerableInt(int start, int length)
|
|
|
|
|
{
|
|
|
|
|
this.start = start;
|
|
|
|
|
this.length = length;
|
|
|
|
|
}
|
|
|
|
|
public static EnumerableInt Range(int start, int length) => new EnumerableInt(start, length);
|
|
|
|
|
public static EnumerableInt StartEnd(int start, int end) => new EnumerableInt(start, end - start);
|
|
|
|
|
IEnumerator<int> IEnumerable<int>.GetEnumerator() => GetEnumerator();
|
|
|
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public Enumerator GetEnumerator() => new Enumerator(start, start + length);
|
|
|
|
|
public struct Enumerator : IEnumerator<int>
|
|
|
|
|
{
|
|
|
|
|
private readonly int _max;
|
|
|
|
|
private int _current;
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public Enumerator(int max, int current)
|
|
|
|
|
{
|
|
|
|
|
_max = max;
|
|
|
|
|
_current = current - 1;
|
|
|
|
|
}
|
|
|
|
|
public int Current
|
|
|
|
|
{
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
get => _current;
|
|
|
|
|
}
|
|
|
|
|
object IEnumerator.Current => Current;
|
2023-12-24 18:11:20 +08:00
|
|
|
|
|
2024-01-07 18:52:54 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public bool MoveNext() => ++_current < _max;
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public void Reset() { }
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public void Dispose() { }
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-24 18:11:20 +08:00
|
|
|
|
internal static unsafe class UnmanagedArrayUtility
|
|
|
|
|
{
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2023-12-31 17:58:20 +08:00
|
|
|
|
public static T* New<T>(int capacity) where T : unmanaged
|
2023-12-24 18:11:20 +08:00
|
|
|
|
{
|
2023-12-31 17:58:20 +08:00
|
|
|
|
return (T*)Marshal.AllocHGlobal(Marshal.SizeOf<T>() * capacity).ToPointer();
|
2023-12-24 18:11:20 +08:00
|
|
|
|
}
|
2024-01-07 18:52:54 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public static void New<T>(out T* ptr, int capacity) where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
ptr = (T*)Marshal.AllocHGlobal(Marshal.SizeOf<T>() * capacity).ToPointer();
|
|
|
|
|
}
|
2023-12-24 18:11:20 +08:00
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2023-12-31 17:58:20 +08:00
|
|
|
|
public static T* NewAndInit<T>(int capacity) where T : unmanaged
|
2023-12-24 18:11:20 +08:00
|
|
|
|
{
|
|
|
|
|
int newSize = Marshal.SizeOf(typeof(T)) * capacity;
|
|
|
|
|
byte* newPointer = (byte*)Marshal.AllocHGlobal(newSize).ToPointer();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < newSize; i++)
|
|
|
|
|
*(newPointer + i) = 0;
|
|
|
|
|
|
2023-12-31 17:58:20 +08:00
|
|
|
|
return (T*)newPointer;
|
2023-12-24 18:11:20 +08:00
|
|
|
|
}
|
2024-01-07 18:52:54 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public static void NewAndInit<T>(out T* ptr, int capacity) where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
int newSize = Marshal.SizeOf(typeof(T)) * capacity;
|
|
|
|
|
byte* newPointer = (byte*)Marshal.AllocHGlobal(newSize).ToPointer();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < newSize; i++)
|
|
|
|
|
*(newPointer + i) = 0;
|
|
|
|
|
|
|
|
|
|
ptr = (T*)newPointer;
|
|
|
|
|
}
|
2023-12-24 18:11:20 +08:00
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public static void Free(void* pointer)
|
|
|
|
|
{
|
|
|
|
|
Marshal.FreeHGlobal(new IntPtr(pointer));
|
|
|
|
|
}
|
2024-01-07 18:52:54 +08:00
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public static void Free<T>(ref T* pointer, ref int length) where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
Marshal.FreeHGlobal(new IntPtr(pointer));
|
|
|
|
|
pointer = null;
|
|
|
|
|
length = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public static T* Clone<T>(T* sourcePtr, int length) where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
T* clone = New<T>(length);
|
|
|
|
|
for (int i = 0; i < length; i++)
|
2024-02-07 22:16:41 +08:00
|
|
|
|
{
|
2024-01-07 18:52:54 +08:00
|
|
|
|
clone[i] = sourcePtr[i];
|
2024-02-07 22:16:41 +08:00
|
|
|
|
}
|
2024-01-07 18:52:54 +08:00
|
|
|
|
return clone;
|
|
|
|
|
}
|
2023-12-24 18:11:20 +08:00
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2023-12-31 17:58:20 +08:00
|
|
|
|
public static T* Resize<T>(void* oldPointer, int newCount) where T : unmanaged
|
2023-12-24 18:11:20 +08:00
|
|
|
|
{
|
2023-12-31 17:58:20 +08:00
|
|
|
|
return (T*)(Marshal.ReAllocHGlobal(
|
2023-12-24 18:11:20 +08:00
|
|
|
|
new IntPtr(oldPointer),
|
|
|
|
|
new IntPtr(Marshal.SizeOf(typeof(T)) * newCount))).ToPointer();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-01-05 23:49:29 +08:00
|
|
|
|
|
2024-01-07 18:52:54 +08:00
|
|
|
|
public static class CollectionUtility
|
2024-01-05 23:49:29 +08:00
|
|
|
|
{
|
2024-01-07 18:52:54 +08:00
|
|
|
|
public static string EntitiesToString(IEnumerable<int> range, string name)
|
2024-01-05 23:49:29 +08:00
|
|
|
|
{
|
|
|
|
|
return $"{name}({range.Count()}) {{{string.Join(", ", range.OrderBy(o => o))}}})";
|
|
|
|
|
}
|
2024-01-07 18:52:54 +08:00
|
|
|
|
public static string AutoToString<T>(IEnumerable<T> range, string name)
|
|
|
|
|
{
|
|
|
|
|
return $"{name}({range.Count()}) {{{string.Join(", ", range.Select(o => o.ToString()))}}})";
|
|
|
|
|
}
|
2024-01-05 23:49:29 +08:00
|
|
|
|
}
|
2024-01-07 18:52:54 +08:00
|
|
|
|
}
|