Repository URL to install this package:
Version:
1.3.1 ▾
|
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Fluctio.FluctioSim.Utils.Extensions;
using JetBrains.Annotations;
using MoreLinq;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.Rendering;
namespace Fluctio.FluctioSim.Utils.General
{
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
[SuppressMessage("ReSharper", "UnusedMember.Global")]
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
public static class Util
{
public static Material DefaultMaterial => GraphicsSettings.currentRenderPipeline.defaultMaterial;
public static Material DefaultTerrainMaterial => GraphicsSettings.currentRenderPipeline.defaultTerrainMaterial;
public static Assembly[] AllDomainAssemblies => AppDomain.CurrentDomain.GetAssemblies();
[Pure] public static string GetBackingFieldName(string propertyName) => $"<{propertyName}>k__BackingField";
[Pure] public static bool NotNull<T>(T obj) => obj != null;
[Pure] public static T Identity<T>(T obj) => obj;
[Pure] public static Func<T, bool> Not<T>(T obj) => (obj2 => !Equals(obj, obj2));
[Pure] [CanBeNull] public static string NullIfWhiteSpace([CanBeNull] this string str) => string.IsNullOrWhiteSpace(str) ? null : str;
[Pure] public static Uri FollowRelative(this Uri baseUri, string path) => new(baseUri, path);
[Pure] public static Uri FollowRelative(this Uri baseUri, Uri path) => new(baseUri, path);
public static void CheckMultibyteLength(this string str, int length, string paramName)
{
var stringInfo = new StringInfo(str);
if (stringInfo.LengthInTextElements != length)
{
throw new ArgumentException($"Argument should contain exactly {length} character(s) (multibyte characters allowed)", paramName);
}
}
public static async Task WaitTill(DateTime dateTime, TimeSpan? checkInternal = null, CancellationToken cancellationToken = default)
{
if (dateTime == DateTime.MaxValue)
{
await Task.Delay(-1, cancellationToken);
}
checkInternal ??= TimeSpan.FromDays(1);
var timeLeft = dateTime - DateTime.UtcNow;
while (timeLeft >= checkInternal)
{
await Task.Delay(checkInternal.Value, cancellationToken);
timeLeft = dateTime - DateTime.UtcNow;
}
if (timeLeft > TimeSpan.Zero)
{
await Task.Delay(timeLeft, cancellationToken);
}
}
public static async void ExecuteAfter(Action action, DateTime dateTime, TimeSpan? checkInternal = null, CancellationToken cancellationToken = default)
{
if (dateTime == DateTime.MaxValue)
{
return;
}
try
{
await WaitTill(dateTime, checkInternal, cancellationToken);
action();
}
catch (OperationCanceledException)
{
// do nothing, this is intended
}
}
public static JObject ParseJwt(string jwtString)
{
var parts = jwtString.Split('.', 4);
if (parts.Length != 3)
{
throw new ArgumentException("Should consist of exactly 3 parts separated by a dot", nameof(jwtString));
}
var payloadBase64 = parts[1];
var payloadJson = payloadBase64.FromBase64UrlSafe().Decode(Encoding.UTF8);
var payload = JObject.Parse(payloadJson);
return payload;
}
public static string ToQueryString(this IDictionary<string, string> queryParams)
{
return queryParams
.Where(pair => pair.Value != null)
.Select(pair => KeyValuePair.Create(WebUtility.UrlEncode(pair.Key), WebUtility.UrlEncode(pair.Value)))
.Select(pair => pair.Value == "" ? pair.Key : $"{pair.Key}={pair.Value}")
.ToDelimitedString("&");
}
public static async Task WaitWithoutLockAsync(this SemaphoreSlim semaphore, CancellationToken cancellationToken = default)
{
if (semaphore.CurrentCount > 0)
{
return;
}
await semaphore.WaitAsync(cancellationToken);
semaphore.Release();
}
/**
* Treats float as a scale change and normalizes it.
* <example>
* <code>0.1f.NormalizeAsScale() == 10</code>
* <code>-5f.NormalizeAsScale() == 5</code>
* <code>(-1/7f).NormalizeAsScale() == 7</code>
* </example>
*/
[Pure]
public static float NormalizeAsScale(float scale)
{
var absoluteScale = Mathf.Abs(scale);
return (absoluteScale < 1) ? (1 / absoluteScale) : absoluteScale;
}
private static readonly SynchronizationContext MainThreadContext = SynchronizationContext.Current;
public static void ExecuteOnMainThread(Action action)
{
MainThreadContext.Post(_ => action(), null);
}
}
}