< Summary

Class:DCL.Helpers.UtilsDummyJsonUtilityFromArray[T]
Assembly:Utils
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Helpers/Utils/Utils.cs
Covered lines:2
Uncovered lines:0
Coverable lines:2
Total lines:534
Line coverage:100% (2 of 2)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
GetFromJsonArray(...)0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Helpers/Utils/Utils.cs

#LineLine coverage
 1#if UNITY_WEBGL && !UNITY_EDITOR
 2#define WEB_PLATFORM
 3#endif
 4
 5using System;
 6using System.Collections;
 7using System.Collections.Generic;
 8using System.Linq;
 9using DCL.Configuration;
 10using TMPro;
 11using UnityEngine;
 12using UnityEngine.Assertions;
 13using UnityEngine.EventSystems;
 14using UnityEngine.Networking;
 15using UnityEngine.UI;
 16
 17namespace DCL.Helpers
 18{
 19    public static class Utils
 20    {
 21        public static Dictionary<string, Material> staticMaterials;
 22
 23        public static Material EnsureResourcesMaterial(string path)
 24        {
 25            if (staticMaterials == null)
 26            {
 27                staticMaterials = new Dictionary<string, Material>();
 28            }
 29
 30            if (!staticMaterials.ContainsKey(path))
 31            {
 32                Material material = Resources.Load(path) as Material;
 33
 34                if (material != null)
 35                {
 36                    staticMaterials.Add(path, material);
 37                }
 38
 39                return material;
 40            }
 41
 42            return staticMaterials[path];
 43        }
 44
 45        public static void CleanMaterials(Renderer r)
 46        {
 47            if (r != null)
 48            {
 49                foreach (Material m in r.materials)
 50                {
 51                    if (m != null)
 52                    {
 53                        Material.Destroy(m);
 54                    }
 55                }
 56            }
 57        }
 58
 59        public static Vector2[] FloatArrayToV2List(float[] uvs)
 60        {
 61            Vector2[] uvsResult = new Vector2[uvs.Length / 2];
 62            int uvsResultIndex = 0;
 63
 64            for (int i = 0; i < uvs.Length;)
 65            {
 66                Vector2 tmpUv = Vector2.zero;
 67                tmpUv.x = uvs[i++];
 68                tmpUv.y = uvs[i++];
 69
 70                uvsResult[uvsResultIndex++] = tmpUv;
 71            }
 72
 73            return uvsResult;
 74        }
 75
 76        public static void ResetLocalTRS(this Transform t)
 77        {
 78            t.localPosition = Vector3.zero;
 79            t.localRotation = Quaternion.identity;
 80            t.localScale = Vector3.one;
 81        }
 82
 83        public static void SetToMaxStretch(this RectTransform t)
 84        {
 85            t.anchorMin = Vector2.zero;
 86            t.offsetMin = Vector2.zero;
 87            t.anchorMax = Vector2.one;
 88            t.offsetMax = Vector2.one;
 89            t.sizeDelta = Vector2.zero;
 90            t.anchoredPosition = Vector2.zero;
 91        }
 92
 93        public static void SetToCentered(this RectTransform t)
 94        {
 95            t.anchorMin = Vector2.one * 0.5f;
 96            t.offsetMin = Vector2.one * 0.5f;
 97            t.anchorMax = Vector2.one * 0.5f;
 98            t.offsetMax = Vector2.one * 0.5f;
 99            t.sizeDelta = Vector2.one * 100;
 100        }
 101
 102        public static void SetToBottomLeft(this RectTransform t)
 103        {
 104            t.anchorMin = Vector2.zero;
 105            t.offsetMin = Vector2.zero;
 106            t.anchorMax = Vector2.zero;
 107            t.offsetMax = Vector2.zero;
 108            t.sizeDelta = Vector2.one * 100;
 109        }
 110
 111        public static void ForceUpdateLayout(this RectTransform rt, bool delayed = true)
 112        {
 113            if (!rt.gameObject.activeInHierarchy)
 114                return;
 115
 116            if (delayed)
 117                CoroutineStarter.Start(ForceUpdateLayoutRoutine(rt));
 118            else
 119            {
 120                Utils.InverseTransformChildTraversal<RectTransform>(
 121                    (x) => { Utils.ForceRebuildLayoutImmediate(x); },
 122                    rt);
 123            }
 124        }
 125
 126        /// <summary>
 127        /// Reimplementation of the LayoutRebuilder.ForceRebuildLayoutImmediate() function (Unity UI API) for make it mo
 128        /// </summary>
 129        /// <param name="rectTransformRoot">Root from which to rebuild.</param>
 130        public static void ForceRebuildLayoutImmediate(RectTransform rectTransformRoot)
 131        {
 132            if (rectTransformRoot == null)
 133                return;
 134
 135            // NOTE(Santi): It seems to be very much cheaper to execute the next instructions manually than execute dire
 136            //              'LayoutRebuilder.ForceRebuildLayoutImmediate()', that theorically already contains these ins
 137            var layoutElements = rectTransformRoot.GetComponentsInChildren(typeof(ILayoutElement), true).ToList();
 138            layoutElements.RemoveAll(e => (e is Behaviour && !((Behaviour) e).isActiveAndEnabled) || e is TextMeshProUGU
 139            foreach (var layoutElem in layoutElements)
 140            {
 141                (layoutElem as ILayoutElement).CalculateLayoutInputHorizontal();
 142                (layoutElem as ILayoutElement).CalculateLayoutInputVertical();
 143            }
 144
 145            var layoutControllers = rectTransformRoot.GetComponentsInChildren(typeof(ILayoutController), true).ToList();
 146            layoutControllers.RemoveAll(e => e is Behaviour && !((Behaviour) e).isActiveAndEnabled);
 147            foreach (var layoutCtrl in layoutControllers)
 148            {
 149                (layoutCtrl as ILayoutController).SetLayoutHorizontal();
 150                (layoutCtrl as ILayoutController).SetLayoutVertical();
 151            }
 152        }
 153
 154        private static IEnumerator ForceUpdateLayoutRoutine(RectTransform rt)
 155        {
 156            yield return null;
 157
 158            Utils.InverseTransformChildTraversal<RectTransform>(
 159                (x) => { Utils.ForceRebuildLayoutImmediate(x); },
 160                rt);
 161        }
 162
 163        public static void InverseTransformChildTraversal<TComponent>(Action<TComponent> action, Transform startTransfor
 164            where TComponent : Component
 165        {
 166            if (startTransform == null)
 167                return;
 168
 169            foreach (Transform t in startTransform)
 170            {
 171                InverseTransformChildTraversal(action, t);
 172            }
 173
 174            var component = startTransform.GetComponent<TComponent>();
 175
 176            if (component != null)
 177            {
 178                action.Invoke(component);
 179            }
 180        }
 181
 182        public static void ForwardTransformChildTraversal<TComponent>(Func<TComponent, bool> action, Transform startTran
 183            where TComponent : Component
 184        {
 185            Assert.IsTrue(startTransform != null, "startTransform must not be null");
 186
 187            var component = startTransform.GetComponent<TComponent>();
 188
 189            if (component != null)
 190            {
 191                if (!action.Invoke(component))
 192                    return;
 193            }
 194
 195            foreach (Transform t in startTransform)
 196            {
 197                ForwardTransformChildTraversal(action, t);
 198            }
 199        }
 200
 201        public static T GetOrCreateComponent<T>(this GameObject gameObject) where T : UnityEngine.Component
 202        {
 203            T component = gameObject.GetComponent<T>();
 204
 205            if (!component)
 206            {
 207                return gameObject.AddComponent<T>();
 208            }
 209
 210            return component;
 211        }
 212
 213        public static WebRequestAsyncOperation FetchTexture(string textureURL, bool isReadable, Action<Texture2D> OnSucc
 214        {
 215            //NOTE(Brian): This closure is called when the download is a success.
 216            void SuccessInternal(UnityWebRequest request)
 217            {
 218                OnSuccess?.Invoke(DownloadHandlerTexture.GetContent(request));
 219            }
 220
 221            var asyncOp = DCL.Environment.i.platform.webRequest.GetTexture(
 222                url: textureURL,
 223                OnSuccess: SuccessInternal,
 224                OnFail: OnFail,
 225                isReadable: isReadable);
 226
 227            return asyncOp;
 228        }
 229
 230        public static bool SafeFromJsonOverwrite(string json, object objectToOverwrite)
 231        {
 232            try
 233            {
 234                JsonUtility.FromJsonOverwrite(json, objectToOverwrite);
 235            }
 236            catch (System.ArgumentException e)
 237            {
 238                Debug.LogError("ArgumentException Fail!... Json = " + json + " " + e.ToString());
 239                return false;
 240            }
 241
 242            return true;
 243        }
 244
 245        public static T FromJsonWithNulls<T>(string json) { return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json
 246
 247        public static T SafeFromJson<T>(string json)
 248        {
 249            ProfilingEvents.OnMessageDecodeStart?.Invoke("Misc");
 250
 251            T returningValue = default(T);
 252
 253            if (!string.IsNullOrEmpty(json))
 254            {
 255                try
 256                {
 257                    returningValue = JsonUtility.FromJson<T>(json);
 258                }
 259                catch (System.ArgumentException e)
 260                {
 261                    Debug.LogError("ArgumentException Fail!... Json = " + json + " " + e.ToString());
 262                }
 263            }
 264
 265            ProfilingEvents.OnMessageDecodeEnds?.Invoke("Misc");
 266
 267            return returningValue;
 268        }
 269
 270        public static GameObject AttachPlaceholderRendererGameObject(UnityEngine.Transform targetTransform)
 271        {
 272            var placeholderRenderer = GameObject.CreatePrimitive(PrimitiveType.Cube).GetComponent<MeshRenderer>();
 273
 274            placeholderRenderer.material = Resources.Load<Material>("Materials/AssetLoading");
 275            placeholderRenderer.transform.SetParent(targetTransform);
 276            placeholderRenderer.transform.localPosition = Vector3.zero;
 277            placeholderRenderer.name = "PlaceholderRenderer";
 278
 279            return placeholderRenderer.gameObject;
 280        }
 281
 282        public static void SafeDestroy(UnityEngine.Object obj)
 283        {
 284#if UNITY_EDITOR
 285            if (Application.isPlaying)
 286                UnityEngine.Object.Destroy(obj);
 287            else
 288                UnityEngine.Object.DestroyImmediate(obj, false);
 289#else
 290                UnityEngine.Object.Destroy(obj);
 291#endif
 292        }
 293
 294        /**
 295         * Transforms a grid position into a world-relative 3d position
 296         */
 297        public static Vector3 GridToWorldPosition(float xGridPosition, float yGridPosition)
 298        {
 299            return new Vector3(
 300                x: xGridPosition * ParcelSettings.PARCEL_SIZE,
 301                y: 0f,
 302                z: yGridPosition * ParcelSettings.PARCEL_SIZE
 303            );
 304        }
 305
 306        /**
 307         * Transforms a world position into a grid position
 308         */
 309        public static Vector2Int WorldToGridPosition(Vector3 worldPosition)
 310        {
 311            return new Vector2Int(
 312                (int) Mathf.Floor(worldPosition.x / ParcelSettings.PARCEL_SIZE),
 313                (int) Mathf.Floor(worldPosition.z / ParcelSettings.PARCEL_SIZE)
 314            );
 315        }
 316
 317        public static Vector2 WorldToGridPositionUnclamped(Vector3 worldPosition)
 318        {
 319            return new Vector2(
 320                worldPosition.x / ParcelSettings.PARCEL_SIZE,
 321                worldPosition.z / ParcelSettings.PARCEL_SIZE
 322            );
 323        }
 324
 325        public static bool AproxComparison(this Color color1, Color color2, float tolerance = 0.01f) // tolerance of rou
 326        {
 327            if (Mathf.Abs(color1.r - color2.r) < tolerance
 328                && Mathf.Abs(color1.g - color2.g) < tolerance
 329                && Mathf.Abs(color1.b - color2.b) < tolerance)
 330            {
 331                return true;
 332            }
 333
 334            return false;
 335        }
 336
 337        public static T ParseJsonArray<T>(string jsonArray) where T : IEnumerable => DummyJsonUtilityFromArray<T>.GetFro
 338
 339        [Serializable]
 340        private class DummyJsonUtilityFromArray<T> where T : IEnumerable //UnityEngine.JsonUtility is really fast but ca
 341        {
 342            [SerializeField]
 343            private T value;
 344
 345            public static T GetFromJsonArray(string jsonArray)
 346            {
 5347                string newJson = $"{{ \"value\": {jsonArray}}}";
 5348                return JsonUtility.FromJson<Utils.DummyJsonUtilityFromArray<T>>(newJson).value;
 349            }
 350        }
 351
 352        private static int lockedInFrame = -1;
 353        public static bool LockedThisFrame() => lockedInFrame == Time.frameCount;
 354
 355        //NOTE(Brian): Made as an independent flag because the CI doesn't work well with the Cursor.lockState check.
 356        public static bool isCursorLocked { get; private set; } = false;
 357
 358        public static void LockCursor()
 359        {
 360#if WEB_PLATFORM
 361            //TODO(Brian): Encapsulate all this mechanism to a new MouseLockController and branch
 362            //             behaviour using strategy pattern instead of this.
 363            if (isCursorLocked)
 364            {
 365                return;
 366            }
 367            if (requestedUnlock || requestedLock)
 368            {
 369                return;
 370            }
 371            requestedLock = true;
 372#else
 373            isCursorLocked = true;
 374            Cursor.visible = false;
 375#endif
 376            Cursor.lockState = CursorLockMode.Locked;
 377            lockedInFrame = Time.frameCount;
 378
 379            EventSystem.current?.SetSelectedGameObject(null);
 380        }
 381
 382        public static void UnlockCursor()
 383        {
 384#if WEB_PLATFORM
 385            //TODO(Brian): Encapsulate all this mechanism to a new MouseLockController and branch
 386            //             behaviour using strategy pattern instead of this.
 387            if (!isCursorLocked)
 388            {
 389                return;
 390            }
 391            if (requestedUnlock || requestedLock)
 392            {
 393                return;
 394            }
 395            requestedUnlock = true;
 396#else
 397            isCursorLocked = false;
 398            Cursor.visible = true;
 399#endif
 400            Cursor.lockState = CursorLockMode.None;
 401
 402            EventSystem.current?.SetSelectedGameObject(null);
 403        }
 404
 405        #region BROWSER_ONLY
 406
 407        //TODO(Brian): Encapsulate all this mechanism to a new MouseLockController and branch
 408        //             behaviour using strategy pattern instead of this.
 409        private static bool requestedUnlock = false;
 410        private static bool requestedLock = false;
 411
 412        // NOTE: This should come from browser's pointerlockchange callback
 413        public static void BrowserSetCursorState(bool locked)
 414        {
 415            if (!locked && !requestedUnlock)
 416            {
 417                Cursor.lockState = CursorLockMode.None;
 418            }
 419
 420            isCursorLocked = locked;
 421            Cursor.visible = !locked;
 422            requestedUnlock = false;
 423            requestedLock = false;
 424        }
 425
 426        #endregion
 427
 428        public static void DestroyAllChild(this Transform transform)
 429        {
 430            foreach (Transform child in transform)
 431            {
 432                UnityEngine.Object.Destroy(child.gameObject);
 433            }
 434        }
 435
 436        public static List<Vector2Int> GetBottomLeftZoneArray(Vector2Int bottomLeftAnchor, Vector2Int size)
 437        {
 438            List<Vector2Int> coords = new List<Vector2Int>();
 439
 440            for (int x = bottomLeftAnchor.x; x < bottomLeftAnchor.x + size.x; x++)
 441            {
 442                for (int y = bottomLeftAnchor.y; y < bottomLeftAnchor.y + size.y; y++)
 443                {
 444                    coords.Add(new Vector2Int(x, y));
 445                }
 446            }
 447
 448            return coords;
 449        }
 450
 451        public static List<Vector2Int> GetCenteredZoneArray(Vector2Int center, Vector2Int size)
 452        {
 453            List<Vector2Int> coords = new List<Vector2Int>();
 454
 455            for (int x = center.x - size.x; x < center.x + size.x; x++)
 456            {
 457                for (int y = center.y - size.y; y < center.y + size.y; y++)
 458                {
 459                    coords.Add(new Vector2Int(x, y));
 460                }
 461            }
 462
 463            return coords;
 464        }
 465
 466        public static void DrawRectGizmo(Rect rect, Color color, float duration)
 467        {
 468            Vector3 tl2 = new Vector3(rect.xMin, rect.yMax, 0);
 469            Vector3 bl2 = new Vector3(rect.xMin, rect.yMin, 0);
 470            Vector3 tr2 = new Vector3(rect.xMax, rect.yMax, 0);
 471            Vector3 br2 = new Vector3(rect.xMax, rect.yMin, 0);
 472
 473            Debug.DrawLine(tl2, bl2, color, duration);
 474            Debug.DrawLine(tl2, tr2, color, duration);
 475            Debug.DrawLine(bl2, br2, color, duration);
 476            Debug.DrawLine(tr2, br2, color, duration);
 477        }
 478
 479        public static string ToUpperFirst(this string value)
 480        {
 481            if (!string.IsNullOrEmpty(value))
 482            {
 483                var capital = char.ToUpper(value[0]);
 484                value = capital + value.Substring(1);
 485            }
 486
 487            return value;
 488        }
 489
 490        public static Vector3 Sanitize(Vector3 value)
 491        {
 492            float x = float.IsInfinity(value.x) ? 0 : value.x;
 493            float y = float.IsInfinity(value.y) ? 0 : value.y;
 494            float z = float.IsInfinity(value.z) ? 0 : value.z;
 495
 496            return new Vector3(x, y, z);
 497        }
 498
 499        public static bool CompareFloats( float a, float b, float precision = 0.1f ) { return Mathf.Abs(a - b) < precisi
 500
 501        public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple, out T1 key, out T2 value)
 502        {
 503            key = tuple.Key;
 504            value = tuple.Value;
 505        }
 506
 507        /// <summary>
 508        /// Set a layer to the given transform and its child
 509        /// </summary>
 510        /// <param name="transform"></param>
 511        public static void SetLayerRecursively(Transform transform, int layer)
 512        {
 513            transform.gameObject.layer = layer;
 514            foreach (Transform child in transform)
 515            {
 516                SetLayerRecursively(child, layer);
 517            }
 518        }
 519
 520        /// <summary>
 521        /// Converts a linear float (between 0 and 1) into an exponential curve fitting for audio volume.
 522        /// </summary>
 523        /// <param name="volume">Linear volume float</param>
 524        /// <returns>Exponential volume curve float</returns>
 525        public static float ToVolumeCurve(float volume) { return volume * (2f - volume); }
 526
 527        /// <summary>
 528        /// Takes a linear volume value between 0 and 1, converts to exponential curve and maps to a value fitting for a
 529        /// </summary>
 530        /// <param name="volume">Linear volume (0 to 1)</param>
 531        /// <returns>Value for audio mixer group volume</returns>
 532        public static float ToAudioMixerGroupVolume(float volume) { return (ToVolumeCurve(volume) * 80f) - 80f; }
 533    }
 534}

Methods/Properties

GetFromJsonArray(System.String)