< Summary

Class:DCL.Models.MeshesInfo
Assembly:MeshesInfo
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/MeshesInfo/MeshesInfo.cs
Covered lines:55
Uncovered lines:12
Coverable lines:67
Total lines:175
Line coverage:82% (55 of 67)
Covered branches:0
Total branches:0
Covered methods:15
Total methods:17
Method coverage:88.2% (15 of 17)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
MeshesInfo()0%110100%
UpdateRenderersCollection(...)0%20400%
UpdateRenderersCollection()0%770100%
RecalculateBounds()0%770100%
CleanReferences()0%330100%
UpdateExistingMeshAtIndex(...)0%5.024060%
OverrideRenderers(...)0%220100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/MeshesInfo/MeshesInfo.cs

#LineLine coverage
 1using Cysharp.Threading.Tasks;
 2using System;
 3using System.Collections.Generic;
 4using System.Linq;
 5using DCL.Components;
 6using TMPro;
 7using UnityEngine;
 8
 9namespace DCL.Models
 10{
 11    /// <summary>
 12    /// (NOTE) Kinerius: this class is a data holder that was made in the past for multiple systems to have access to th
 13    /// This has a big architectural issue where if we decide to remove any component (renderer, mesh filter, collider) 
 14    /// from anywhere within the system, we have to explicitly update this class values, it makes no sense,
 15    /// we need to reconsider this class functionality and purpose since it has an ambiguous design and it might be the 
 16    /// </summary>
 17    [Serializable]
 18    public class MeshesInfo
 19    {
 20        public static event Action OnAnyUpdated;
 21        public event Action OnUpdated;
 22        public event Action OnCleanup;
 23
 24        public GameObject innerGameObject;
 25
 26        public GameObject meshRootGameObject
 27        {
 28            get
 29            {
 637730                return meshRootGameObjectValue;
 31            }
 32
 33            set
 34            {
 33635                meshRootGameObjectValue = value;
 33636                UpdateRenderersCollection();
 33637            }
 38        }
 39
 40        GameObject meshRootGameObjectValue;
 41
 2042        public bool RootIsPoolableObject { get; set; }
 43
 44        public IShape currentShape;
 2500045        public Renderer[] renderers { get; private set; }
 46        public MeshFilter[] meshFilters;
 31147        public HashSet<Collider> colliders = new ();
 99548        public Animation animation { get; private set; }
 49
 50        Vector3 lastBoundsCalculationPosition;
 51        Vector3 lastBoundsCalculationScale;
 52        Quaternion lastBoundsCalculationRotation;
 53        Bounds mergedBoundsValue;
 54
 55        public Bounds mergedBounds
 56        {
 57            get
 58            {
 34359                if (meshRootGameObject == null) { RecalculateBounds(); }
 60                else
 61                {
 34362                    if (meshRootGameObject.transform.position != lastBoundsCalculationPosition)
 63                    {
 3864                        mergedBoundsValue.center += meshRootGameObject.transform.position - lastBoundsCalculationPositio
 3865                        lastBoundsCalculationPosition = meshRootGameObject.transform.position;
 66                    }
 67
 34368                    if (meshRootGameObject.transform.lossyScale != lastBoundsCalculationScale ||
 69                        meshRootGameObject.transform.rotation != lastBoundsCalculationRotation)
 14270                        RecalculateBounds();
 71                }
 72
 34373                return mergedBoundsValue;
 74            }
 75
 76            set
 77            {
 078                mergedBoundsValue = value;
 079            }
 80        }
 81
 82        public void UpdateRenderersCollection(Renderer[] renderers, MeshFilter[] meshFilters, Animation animation = null
 83        {
 084            if (meshRootGameObjectValue != null)
 85            {
 086                this.renderers = renderers;
 087                this.meshFilters = meshFilters;
 088                this.animation = animation;
 89
 090                RecalculateBounds();
 091                OnAnyUpdated?.Invoke();
 092                OnUpdated?.Invoke();
 93            }
 094        }
 95
 96        public void UpdateRenderersCollection()
 97        {
 89198            if (meshRootGameObjectValue == null)
 20099                return;
 100
 691101            renderers = meshRootGameObjectValue.GetComponentsInChildren<Renderer>(true);
 691102            meshFilters = meshRootGameObjectValue.GetComponentsInChildren<MeshFilter>(true);
 691103            animation = meshRootGameObjectValue.GetComponentInChildren<Animation>();
 104
 691105            TextMeshPro[] tmpros = meshRootGameObjectValue.GetComponentsInChildren<TextMeshPro>(true);
 106
 691107            if (tmpros.Length > 0)
 108            {
 52109                renderers = renderers.Union(tmpros.Select(x => x.renderer)).ToArray();
 52110                meshFilters = meshFilters.Union(tmpros.Select(x => x.meshFilter)).ToArray();
 111            }
 112
 691113            RecalculateBounds();
 691114            OnAnyUpdated?.Invoke();
 691115            OnUpdated?.Invoke();
 686116        }
 117
 118        public async UniTask RecalculateBounds()
 119        {
 833120            if ((renderers == null || renderers.Length == 0) && colliders.Count == 0)
 121            {
 256122                mergedBoundsValue = new Bounds();
 256123                return;
 124            }
 125
 1731126            await UniTask.WaitForFixedUpdate();
 127
 798128            if (meshRootGameObjectValue == null) return;
 129
 356130            lastBoundsCalculationPosition = meshRootGameObjectValue.transform.position;
 356131            lastBoundsCalculationScale = meshRootGameObjectValue.transform.lossyScale;
 356132            lastBoundsCalculationRotation = meshRootGameObjectValue.transform.rotation;
 133
 356134            mergedBoundsValue = MeshesInfoUtils.BuildMergedBounds(renderers, colliders);
 833135        }
 136
 137        public void CleanReferences()
 138        {
 202139            OnCleanup?.Invoke();
 202140            meshRootGameObjectValue = null;
 202141            animation = null;
 202142            currentShape = null;
 202143            renderers = null;
 202144            colliders.Clear();
 145
 202146            var arrayLength = meshFilters.Length;
 888147            for (int i = 0; i < arrayLength; i++)
 148            {
 242149                meshFilters[i] = null;
 150            }
 202151            innerGameObject = null;
 152
 202153            OnCleanup = null;
 202154        }
 155
 156        public void UpdateExistingMeshAtIndex(Mesh mesh, uint meshFilterIndex = 0)
 157        {
 3158            if (meshFilters != null && meshFilters.Length > meshFilterIndex)
 159            {
 3160                meshFilters[meshFilterIndex].sharedMesh = mesh;
 3161                OnUpdated?.Invoke();
 162            }
 163            else
 164            {
 0165                Debug.LogError(
 166                    $"MeshFilter index {meshFilterIndex} out of bounds - MeshesInfo.UpdateExistingMesh failed");
 167            }
 0168        }
 169
 170        public void OverrideRenderers(Renderer[] renderers)
 171        {
 380172            this.renderers = renderers.Where(r => r != null).ToArray();
 190173        }
 174    }
 175}