using System; using System.Collections.Generic; using Unity.Collections; using UnityEngine; namespace ProceduralToolkit { /// /// Array extensions /// public static class ArrayE { /// /// Gets the next or the first node in the /// public static LinkedListNode NextOrFirst(this LinkedListNode current) { return current.Next ?? current.List.First; } /// /// Gets the previous or the last node in the /// public static LinkedListNode PreviousOrLast(this LinkedListNode current) { return current.Previous ?? current.List.Last; } /// /// Two-dimensional indexer getter /// public static T GetXY(this IReadOnlyList list, Vector2Int position, int width) { return list[position.y*width + position.x]; } /// /// Two-dimensional indexer getter /// public static T GetXY(this IReadOnlyList list, int x, int y, int width) { return list[y*width + x]; } /// /// Two-dimensional indexer getter /// public static T GetXY(this NativeArray list, Vector2Int position, int width) where T : struct { return list[position.y*width + position.x]; } /// /// Two-dimensional indexer getter /// public static T GetXY(this NativeArray list, int x, int y, int width) where T : struct { return list[y*width + x]; } /// /// Two-dimensional indexer setter, ignores IList.IsReadOnly /// public static void SetXY(this IList list, Vector2Int position, int width, T value) { list[position.y*width + position.x] = value; } /// /// Two-dimensional indexer setter, ignores IList.IsReadOnly /// public static void SetXY(this IList list, int x, int y, int width, T value) { list[y*width + x] = value; } /// /// Two-dimensional indexer setter /// public static void SetXY(this NativeArray list, Vector2Int position, int width, T value) where T : struct { list[position.y*width + position.x] = value; } /// /// Two-dimensional indexer setter /// public static void SetXY(this NativeArray list, int x, int y, int width, T value) where T : struct { list[y*width + x] = value; } /// /// Looped indexer getter, allows out of bounds indices /// public static T GetLooped(this IReadOnlyList list, int index) { while (index < 0) { index += list.Count; } if (index >= list.Count) { index %= list.Count; } return list[index]; } /// /// Looped indexer setter, allows out of bounds indices, ignores IList.IsReadOnly /// public static void SetLooped(this IList list, int index, T value) { while (index < 0) { index += list.Count; } if (index >= list.Count) { index %= list.Count; } list[index] = value; } /// /// Checks if is within array bounds /// public static bool IsInBounds(this T[,] array, Vector2Int position) { return IsInBounds(array, position.x, position.y); } /// /// Checks if and are within array bounds /// public static bool IsInBounds(this T[,] array, int x, int y) { if (array == null) throw new ArgumentNullException(nameof(array)); return x >= 0 && x < array.GetLength(0) && y >= 0 && y < array.GetLength(1); } } }