// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) VRMADA, All rights reserved.
//
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using UltimateXR.Extensions.System;
using UnityEngine;
namespace UltimateXR.Extensions.Unity.Math
{
///
/// extensions.
///
public static class Vector2IntExt
{
#region Public Types & Data
///
/// Representation of the negative infinity vector.
///
public static ref readonly Vector2Int NegativeInfinity => ref s_negativeInfinity;
///
/// Representation of the positive infinity vector.
///
public static ref readonly Vector2Int PositiveInfinity => ref s_positiveInfinity;
#endregion
#region Public Methods
///
/// Checks whether any vector component stores an infinity value.
///
/// Vector to check
/// Whether any component has an infinity value
public static bool IsInfinity(this in Vector2Int self)
{
return self.x == int.MinValue || self.x == int.MaxValue || self.y == int.MinValue || self.y == int.MaxValue;
}
///
/// Computes the absolute values of each vector component.
///
/// Input vector
/// Result vector where each component is the absolute value of the input value component
public static Vector2Int Abs(this in Vector2Int self)
{
return new Vector2Int(Mathf.Abs(self.x), Mathf.Abs(self.y));
}
///
/// Clamps the vector components between min and max values.
///
/// Input vector whose values to clamp
/// Minimum component values
/// Maximum component values
/// Clamped vector
public static Vector2Int Clamp(this in Vector2Int self, in Vector2Int min, in Vector2Int max)
{
int[] result = new int[VectorLength];
for (int i = 0; i < VectorLength; ++i)
{
result[i] = Mathf.Clamp(self[i], min[i], max[i]);
}
return result.ToVector2Int();
}
///
/// Replaces NaN component values with valid values.
///
/// Vector whose NaN values to replace
/// Vector with valid values
/// Result vector
public static Vector2Int FillNanWith(this in Vector2Int self, in Vector2Int other)
{
int[] result = new int[VectorLength];
for (int i = 0; i < VectorLength; ++i)
{
result[i] = self.x == int.MinValue || self.x == int.MaxValue ? other[i] : self[i];
}
return result.ToVector2Int();
}
///
/// Transforms an array of ints to a component by component.
///
/// Source data
/// Result vector
public static Vector2Int ToVector2Int(this int[] data)
{
Array.Resize(ref data, VectorLength);
return new Vector2Int(data[0], data[1]);
}
///
/// Tries to parse a from a string.
///
/// Source string
/// Parsed vector or if there was an error
/// Whether the vector was parsed successfully
public static bool TryParse(string s, out Vector2Int result)
{
try
{
result = Parse(s);
return true;
}
catch
{
result = PositiveInfinity;
return false;
}
}
///
/// Parses a from a string.
///
/// Source string
/// Parsed vector
public static Vector2Int Parse(string s)
{
s.ThrowIfNullOrWhitespace(nameof(s));
// Remove the parentheses
s = s.TrimStart(' ', '(', '[');
s = s.TrimEnd(' ', ')', ']');
// split the items
string[] sArray = s.Split(s_cardinalSeparator, VectorLength);
// store as an array
int[] result = new int[VectorLength];
for (int i = 0; i < sArray.Length; ++i)
{
result[i] = int.Parse(sArray[i], CultureInfo.InvariantCulture.NumberFormat);
}
return result.ToVector2Int();
}
///
/// Tries to parse a from a string, asynchronously.
///
/// Source string
/// Optional cancellation token, to cancel the operation
/// Awaitable task returning the parsed vector or null if there was an error
public static Task ParseAsync(string s, CancellationToken ct = default)
{
return Task.Run(() => TryParse(s, out Vector2Int result) ? result : (Vector2Int?)null, ct);
}
#endregion
#region Private Types & Data
private const int VectorLength = 2;
private const string CardinalSeparator = ",";
private static readonly char[] s_cardinalSeparator = CardinalSeparator.ToCharArray();
private static readonly Vector2Int s_negativeInfinity = int.MinValue * Vector2Int.one;
private static readonly Vector2Int s_positiveInfinity = int.MaxValue * Vector2Int.one;
#endregion
}
}