#if DISABLE_DEBUG #undef DEBUG #endif using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; namespace DCFApixels.DragonECS.Core.Internal { internal interface ILinkedNext { int Next { get; } } internal readonly struct LinkedListCountIterator : IEnumerable where T : ILinkedNext { public readonly T[] Array; public readonly int Count; public readonly int StartIndex; public LinkedListCountIterator(T[] array, int count, int startIndex) { Array = array; Count = count; StartIndex = startIndex; } public Enumerator GetEnumerator() { return new Enumerator(Array, Count, StartIndex); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public struct Enumerator : IEnumerator { private readonly T[] _array; private readonly int _count; private int _index; private int _counter; public Enumerator(T[] array, int count, int index) { _array = array; _count = count; _index = index; _counter = 0; } public ref T Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _array[_index]; } } T IEnumerator.Current { get { return _array[_index]; } } object IEnumerator.Current { get { return Current; } } public bool MoveNext() { if (++_counter > _count) { return false; } if (_counter > 1) { _index = _array[_index].Next; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] void IDisposable.Dispose() { } void IEnumerator.Reset() { throw new NotSupportedException(); } } } internal readonly struct LinkedListIterator : IEnumerable where T : ILinkedNext { public readonly T[] Array; public readonly int EndIndex; public readonly int StartIndex; public LinkedListIterator(T[] array, int endIndex, int startIndex) { Array = array; EndIndex = endIndex; StartIndex = startIndex; } public Enumerator GetEnumerator() { return new Enumerator(Array, EndIndex, StartIndex); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public struct Enumerator : IEnumerator { private readonly T[] _array; private readonly int _endIndex; private readonly int _startIndex; private int _nextIndex; private int _index; public ref T Current { get { return ref _array[_index]; } } T IEnumerator.Current { get { return Current; } } object IEnumerator.Current { get { return Current; } } public Enumerator(T[] array, int endIndex, int head) { _array = array; _startIndex = head; _nextIndex = _startIndex; _endIndex = endIndex; _index = _endIndex; } public bool MoveNext() { if (_nextIndex < 0) { return false; } _index = _nextIndex; _nextIndex = _array[_index].Next; return true; } public void Dispose() { } public void Reset() { _nextIndex = _startIndex; _index = _endIndex; } } } internal static class ArrayUtility { public static void ResizeOrCreate(ref T[] array, int newSize) { if (array == null) { array = new T[newSize]; } { Array.Resize(ref array, newSize); } } internal static void UpsizeTwoHead(ref T[] array, int newLength, int separationIndex) { UpsizeTwoHead(ref array, newLength, separationIndex, array.Length - separationIndex); } internal static void UpsizeTwoHead(ref T[] array, int newLength, int leftHeadLength, int rightHeadLength) { if (array.Length > newLength) { return; } var result = new T[newLength]; Array.Copy(array, result, leftHeadLength); // copy left head Array.Copy(array, array.Length - rightHeadLength, result, array.Length - rightHeadLength, rightHeadLength); // copy right head array = result; } public static int NextPow2Safe(int v, int min = 4) { return NextPow2(v < min ? min : v); } public static int NextPow2(int v) { return CeilPow2(v | 1); } public static int CeilPow2Safe(int v, int min = 4) { return CeilPow2(v < min ? min : v); } public static int CeilPow2(int v) { unchecked { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; return ++v; } } public static int CeilPow2_ClampOverflow(int v) { unchecked { const int NO_SIGN_HIBIT = 0x40000000; if ((v & NO_SIGN_HIBIT) != 0) { return int.MaxValue; } return CeilPow2(v); } } public static void Fill(T[] array, T value, int startIndex = 0, int length = -1) { if (length < 0) { length = array.Length; } else { length = startIndex + length; } for (int i = startIndex; i < length; i++) { array[i] = value; } } public static void UpsizeWithoutCopy(ref T[] array, int minSize) { if (array == null || minSize > array.Length) { array = new T[minSize]; } } public static void Upsize(ref T[] array, int minSize) { if (array == null) { array = new T[minSize]; } else if (minSize > array.Length) { Array.Resize(ref array, minSize); } } //public static void UpsizeToCeilPow2(ref T[] array, int newSize, int minSize = 4) //{ // newSize = CeilPow2(newSize < minSize ? minSize : newSize); // if (array == null) // { // array = new T[newSize]; // } // else if (newSize > array.Length) // { // Array.Resize(ref array, newSize); // } //} } internal readonly struct EnumerableInt : IEnumerable { 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) { return new EnumerableInt(start, length); } public static EnumerableInt StartEnd(int start, int end) { return new EnumerableInt(start, end - start); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Enumerator GetEnumerator() { return new Enumerator(start, start + length); } public struct Enumerator : IEnumerator { 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 { return _current; } } object IEnumerator.Current { get { return Current; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { return ++_current < _max; } [MethodImpl(MethodImplOptions.AggressiveInlining)] void IDisposable.Dispose() { } void IEnumerator.Reset() { throw new NotSupportedException(); } } } public static class CollectionUtility { public static string EntitiesToString(IEnumerable range, string name) { return $"{name}({range.Count()}) {{{string.Join(", ", range.OrderBy(o => o))}}})"; } public static string AutoToString(IEnumerable range, string name) { return $"{name}({range.Count()}) {{{string.Join(", ", range.Select(o => o.ToString()))}}})"; } } }