< Summary

Class:DCL.SceneMetricsCounter
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/SceneMetricsCounter/SceneMetricsCounter.cs
Covered lines:113
Uncovered lines:14
Coverable lines:127
Total lines:272
Line coverage:88.9% (113 of 127)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
SceneMetricsCounter()0%110100%
SceneMetricsCounter(...)0%110100%
SceneMetricsCounter(...)0%110100%
Configure(...)0%110100%
Dispose()0%110100%
Enable()0%22093.75%
Disable()0%220100%
ComputeMaxCount()0%110100%
IsInsideTheLimits()0%8.57068.75%
MarkDirty()0%2100%
SendEvent()0%220100%
OnDataChanged[T](...)0%110100%
OnDataChanged(...)0%110100%
UpdateMetrics()0%5.015092.31%
UpdateWorstMetricsOffense()0%7.237083.33%
RaiseMetricsUpdate()0%2.152066.67%

File(s)

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

#LineLine coverage
 1using System;
 2using DCL.Controllers;
 3using DCL.Interface;
 4using DCL.Models;
 5using System.Collections.Generic;
 6using System.Linq;
 7using UnityEngine;
 8using UnityEngine.Assertions;
 9
 10namespace DCL
 11{
 12    public sealed class SceneMetricsCounter : ISceneMetricsCounter
 13    {
 14        public static class LimitsConfig
 15        {
 16            // number of entities
 17            public const int entities = 200;
 18
 19            // Number of faces (per parcel)
 20            public const int triangles = 10000;
 21            public const int bodies = 300;
 22            public const int textures = 10;
 23            public const int materials = 20;
 24            public const int meshes = 200;
 25
 26            public const float height = 20;
 27            public const float visibleRadius = 10;
 28        }
 29
 130        private static bool VERBOSE = false;
 131        private static Logger logger = new Logger("SceneMetricsCounter") { verboseEnabled = VERBOSE };
 32        public event Action<ISceneMetricsCounter> OnMetricsUpdated;
 33
 50934        private SceneMetricsModel maxCountValue = new SceneMetricsModel();
 50935        private SceneMetricsModel currentCountValue = new SceneMetricsModel();
 36
 37        public SceneMetricsModel currentCount
 38        {
 39            get
 40            {
 8241                UpdateMetrics();
 8242                return currentCountValue.Clone();
 43            }
 44        }
 45
 72346        public SceneMetricsModel maxCount => maxCountValue.Clone();
 47
 048        public bool dirty { get; private set; }
 49
 50        private string sceneId;
 51
 52        private Vector2Int scenePosition;
 53
 54        private int sceneParcelCount;
 55
 56        private DataStore_WorldObjects data;
 57        private bool enabled = false;
 58
 659        public SceneMetricsCounter(DataStore_WorldObjects dataStore, string sceneId, Vector2Int scenePosition, int scene
 60        {
 661            this.data = dataStore;
 662            Configure(sceneId, scenePosition, sceneParcelCount);
 663        }
 64
 50365        public SceneMetricsCounter(DataStore_WorldObjects dataStore)
 66        {
 50367            this.data = dataStore;
 50368        }
 69
 70        public void Configure(string sceneId, Vector2Int scenePosition, int sceneParcelCount)
 71        {
 50672            this.sceneId = sceneId;
 50673            this.scenePosition = scenePosition;
 50674            this.sceneParcelCount = sceneParcelCount;
 75
 50676            Assert.IsTrue( !string.IsNullOrEmpty(sceneId), "Scene must have an ID!" );
 50677            maxCountValue = ComputeMaxCount();
 50678        }
 79
 80        public void Dispose()
 81        {
 50382        }
 83
 84
 85        public void Enable()
 86        {
 50687            if ( enabled )
 088                return;
 89
 50690            var sceneData = data.sceneData[sceneId];
 91
 50692            sceneData.materials.OnAdded += OnDataChanged;
 50693            sceneData.materials.OnRemoved += OnDataChanged;
 94
 50695            sceneData.textures.OnAdded += OnDataChanged;
 50696            sceneData.textures.OnRemoved += OnDataChanged;
 97
 50698            sceneData.meshes.OnAdded += OnDataChanged;
 50699            sceneData.meshes.OnRemoved += OnDataChanged;
 100
 506101            sceneData.renderers.OnAdded += OnDataChanged;
 506102            sceneData.renderers.OnRemoved += OnDataChanged;
 103
 506104            sceneData.owners.OnAdded += OnDataChanged;
 506105            sceneData.owners.OnRemoved += OnDataChanged;
 106
 506107            sceneData.triangles.OnChange += OnDataChanged;
 108
 506109            enabled = true;
 506110        }
 111
 112        public void Disable()
 113        {
 503114            if ( !enabled )
 3115                return;
 116
 500117            var sceneData = data.sceneData[sceneId];
 118
 500119            sceneData.materials.OnAdded -= OnDataChanged;
 500120            sceneData.materials.OnRemoved -= OnDataChanged;
 121
 500122            sceneData.textures.OnAdded -= OnDataChanged;
 500123            sceneData.textures.OnRemoved -= OnDataChanged;
 124
 500125            sceneData.meshes.OnAdded -= OnDataChanged;
 500126            sceneData.meshes.OnRemoved -= OnDataChanged;
 127
 500128            sceneData.renderers.OnAdded -= OnDataChanged;
 500129            sceneData.renderers.OnRemoved -= OnDataChanged;
 130
 500131            sceneData.owners.OnAdded -= OnDataChanged;
 500132            sceneData.owners.OnRemoved -= OnDataChanged;
 133
 500134            sceneData.triangles.OnChange -= OnDataChanged;
 135
 500136            enabled = false;
 500137        }
 138
 139        private SceneMetricsModel ComputeMaxCount()
 140        {
 511141            var result = new SceneMetricsModel();
 142
 511143            float log = Mathf.Log(sceneParcelCount + 1, 2);
 511144            float lineal = sceneParcelCount;
 145
 511146            result.triangles = (int) (lineal * LimitsConfig.triangles);
 511147            result.bodies = (int) (lineal * LimitsConfig.bodies);
 511148            result.entities = (int) (lineal * LimitsConfig.entities);
 511149            result.materials = (int) (log * LimitsConfig.materials);
 511150            result.textures = (int) (log * LimitsConfig.textures);
 511151            result.meshes = (int) (log * LimitsConfig.meshes);
 511152            result.sceneHeight = (int) (log * LimitsConfig.height);
 153
 511154            return result;
 155        }
 156
 157        public bool IsInsideTheLimits()
 158        {
 5159            UpdateMetrics();
 5160            SceneMetricsModel limits = ComputeMaxCount();
 5161            SceneMetricsModel usage = currentCountValue;
 162
 5163            if (usage.triangles > limits.triangles)
 0164                return false;
 165
 5166            if (usage.bodies > limits.bodies)
 0167                return false;
 168
 5169            if (usage.entities > limits.entities)
 1170                return false;
 171
 4172            if (usage.materials > limits.materials)
 0173                return false;
 174
 4175            if (usage.textures > limits.textures)
 0176                return false;
 177
 4178            if (usage.meshes > limits.meshes)
 0179                return false;
 180
 4181            return true;
 182        }
 183
 184        private void MarkDirty()
 185        {
 0186            dirty = true;
 0187        }
 188
 189        public void SendEvent()
 190        {
 669191            if (!dirty)
 490192                return;
 193
 179194            dirty = false;
 195
 179196            UpdateMetrics();
 197
 179198            Interface.WebInterface.ReportOnMetricsUpdate(sceneId, currentCountValue.ToMetricsModel(), maxCount.ToMetrics
 179199        }
 200
 201        void OnDataChanged<T>(T obj)
 202            where T : class
 203        {
 2686204            MarkDirty();
 2686205        }
 206
 207        void OnDataChanged(int obj1, int obj2)
 208        {
 449209            MarkDirty();
 449210        }
 211
 212        private void UpdateMetrics()
 213        {
 266214            if (string.IsNullOrEmpty(sceneId))
 0215                return;
 216
 266217            var sceneData = data?.sceneData[sceneId];
 218
 266219            if ( sceneData != null )
 220            {
 266221                currentCountValue.materials = sceneData.materials.Count();
 266222                currentCountValue.textures = sceneData.textures.Count();
 266223                currentCountValue.meshes = sceneData.meshes.Count();
 266224                currentCountValue.entities = sceneData.owners.Count();
 266225                currentCountValue.bodies = sceneData.renderers.Count();
 266226                currentCountValue.triangles = sceneData.triangles.Get() / 3;
 227            }
 228
 266229            logger.Verbose($"Current metrics: {currentCountValue}");
 266230            RaiseMetricsUpdate();
 266231        }
 232
 233        private void UpdateWorstMetricsOffense()
 234        {
 266235            DataStore_SceneMetrics metricsData = DataStore.i.Get<DataStore_SceneMetrics>();
 236
 266237            if ( maxCountValue != null && metricsData.worstMetricOffenseComputeEnabled.Get() )
 238            {
 266239                bool isOffending = currentCountValue > maxCountValue;
 240
 266241                if ( !isOffending )
 265242                    return;
 243
 1244                bool firstOffense = false;
 245
 1246                if (!metricsData.worstMetricOffenses.ContainsKey(sceneId))
 247                {
 1248                    firstOffense = true;
 1249                    metricsData.worstMetricOffenses[sceneId] = currentCountValue.Clone();
 250                }
 251
 1252                SceneMetricsModel worstOffense = metricsData.worstMetricOffenses[sceneId];
 1253                SceneMetricsModel currentOffense = maxCountValue - currentCountValue;
 254
 1255                if ( firstOffense )
 1256                    logger.Verbose($"New offending scene {sceneId} ({scenePosition})!\n{currentCountValue}");
 257
 1258                if ( currentOffense < worstOffense )
 1259                    return;
 260
 0261                metricsData.worstMetricOffenses[sceneId] = currentOffense;
 0262                logger.Verbose($"New offending scene {sceneId} {scenePosition}!\nmetrics: {currentCountValue}\nlimits: {
 263            }
 0264        }
 265
 266        private void RaiseMetricsUpdate()
 267        {
 266268            UpdateWorstMetricsOffense();
 266269            OnMetricsUpdated?.Invoke(this);
 0270        }
 271    }
 272}