< Summary

Class:DCL.ParcelScenesCleaner
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/ParcelScenesCleaner.cs
Covered lines:56
Uncovered lines:15
Coverable lines:71
Total lines:174
Line coverage:78.8% (56 of 71)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
MarkedEntityInfo(...)0%2100%
MarkedSharedComponentInfo(...)0%2100%
ParcelScenesCleaner()0%110100%
Initialize()0%110100%
OnRendererStateChange(...)0%220100%
MarkForCleanup(...)0%4.024088.89%
MarkRootEntityForCleanup(...)0%110100%
MarkDisposableComponentForCleanup(...)0%110100%
CleanMarkedEntities()0%110100%
CleanMarkedEntitiesAsync()0%27.8921075%
CleanupEntitiesCoroutine()0%440100%
Dispose()0%220100%

File(s)

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

#LineLine coverage
 1using DCL.Controllers;
 2using DCL.Models;
 3using System.Collections;
 4using System.Collections.Generic;
 5using UnityEngine;
 6using Object = UnityEngine.Object;
 7
 8namespace DCL
 9{
 10    public class ParcelScenesCleaner : IParcelScenesCleaner
 11    {
 12        const float MAX_TIME_BUDGET = 0.01f;
 13
 14        private struct MarkedEntityInfo
 15        {
 16            public ParcelScene scene;
 17            public IDCLEntity entity;
 18
 19            public MarkedEntityInfo(ParcelScene scene, IDCLEntity entity)
 20            {
 021                this.scene = scene;
 022                this.entity = entity;
 023            }
 24        }
 25
 26        private struct MarkedSharedComponentInfo
 27        {
 28            public ParcelScene scene;
 29            public string componentId;
 30
 31            public MarkedSharedComponentInfo(ParcelScene scene, string componentId)
 32            {
 033                this.scene = scene;
 034                this.componentId = componentId;
 035            }
 36        }
 37
 66638        Queue<IDCLEntity> entitiesMarkedForCleanup = new Queue<IDCLEntity>();
 66639        Queue<MarkedEntityInfo> rootEntitiesMarkedForCleanup = new Queue<MarkedEntityInfo>();
 66640        Queue<MarkedSharedComponentInfo> disposableComponentsMarkedForCleanup = new Queue<MarkedSharedComponentInfo>();
 41
 42        Coroutine removeEntitiesCoroutine;
 43
 66644        public ParcelScenesCleaner ()
 45        {
 66646            removeEntitiesCoroutine = CoroutineStarter.Start(CleanupEntitiesCoroutine());
 66647            CommonScriptableObjects.rendererState.OnChange += OnRendererStateChange;
 66648        }
 49
 50        public void Initialize()
 51        {
 66652            Environment.i.platform.memoryManager.OnCriticalMemory += CleanMarkedEntities;
 66653        }
 54
 55        private void OnRendererStateChange(bool isEnable, bool prevState)
 56        {
 10457            if (!isEnable)
 58            {
 159                CleanMarkedEntities();
 160                Resources.UnloadUnusedAssets();
 61            }
 10462        }
 63
 64        public void MarkForCleanup(IDCLEntity entity)
 65        {
 49366            if (entity.markedForCleanup)
 067                return;
 68
 49369            entity.markedForCleanup = true;
 70
 49371            if (entity.gameObject != null)
 48972                entity.gameObject.SetActive(false);
 73
 74#if UNITY_EDITOR
 49375            if (entity.gameObject != null)
 48976                entity.gameObject.name += "-MARKED-FOR-CLEANUP";
 77#endif
 78
 49379            entitiesMarkedForCleanup.Enqueue(entity);
 49380        }
 81
 82        // When removing all entities from a scene, we need to separate the root entities, as stated in ParcelScene,
 83        // to avoid traversing a lot of child entities in the same frame and other problems
 97084        public void MarkRootEntityForCleanup(IParcelScene scene, IDCLEntity entity) { rootEntitiesMarkedForCleanup.Enque
 85
 103286        public void MarkDisposableComponentForCleanup(IParcelScene scene, string componentId) { disposableComponentsMark
 87
 88        public void CleanMarkedEntities()
 89        {
 69290            CleanMarkedEntitiesAsync(true).MoveNext();
 69291        }
 92
 93        public IEnumerator CleanMarkedEntitiesAsync(bool immediate = false)
 94        {
 637895            float lastTime = Time.unscaledTime;
 96
 689497            while (disposableComponentsMarkedForCleanup.Count > 0)
 98            {
 51699                MarkedSharedComponentInfo markedSharedComponentInfo = disposableComponentsMarkedForCleanup.Dequeue();
 516100                markedSharedComponentInfo.scene.SharedComponentDispose(markedSharedComponentInfo.componentId);
 101
 516102                if (DCLTime.realtimeSinceStartup - lastTime >= MAX_TIME_BUDGET && !immediate)
 103                {
 0104                    yield return null;
 0105                    lastTime = Time.unscaledTime;
 106                }
 107            }
 108
 6378109            HashSet<ParcelScene> scenesToRemove = new HashSet<ParcelScene>();
 110
 111            // If we have root entities queued for removal, we call Parcel Scene's RemoveEntity()
 112            // so that the child entities end up recursively in the entitiesMarkedForCleanup queue
 6863113            while (rootEntitiesMarkedForCleanup.Count > 0)
 114            {
 485115                MarkedEntityInfo markedEntityInfo = rootEntitiesMarkedForCleanup.Dequeue();
 485116                markedEntityInfo.scene.RemoveEntity(markedEntityInfo.entity.entityId, false);
 117
 485118                if (!scenesToRemove.Contains(markedEntityInfo.scene))
 239119                    scenesToRemove.Add(markedEntityInfo.scene);
 120
 485121                if (!immediate && DCLTime.realtimeSinceStartup - lastTime >= MAX_TIME_BUDGET)
 122                {
 0123                    yield return null;
 0124                    lastTime = Time.unscaledTime;
 125                }
 126            }
 127
 6871128            while (entitiesMarkedForCleanup.Count > 0)
 129            {
 493130                IDCLEntity entity = entitiesMarkedForCleanup.Dequeue();
 493131                entity.SetParent(null);
 493132                entity.Cleanup();
 133
 493134                if (!immediate && DCLTime.realtimeSinceStartup - lastTime >= MAX_TIME_BUDGET)
 135                {
 0136                    yield return null;
 0137                    lastTime = Time.unscaledTime;
 138                }
 139            }
 140
 13234141            foreach (var scene in scenesToRemove)
 142            {
 239143                if (scene != null && !Environment.i.world.state.loadedScenes.ContainsKey(scene.sceneData.id))
 239144                    Object.Destroy(scene.gameObject);
 145
 239146                if (!immediate && DCLTime.realtimeSinceStartup - lastTime >= MAX_TIME_BUDGET)
 147                {
 0148                    yield return null;
 0149                    lastTime = Time.unscaledTime;
 150                }
 151            }
 6378152        }
 153
 154        IEnumerator CleanupEntitiesCoroutine()
 155        {
 5020156            while (true)
 157            {
 5686158                yield return CleanMarkedEntitiesAsync();
 5473159                yield return null;
 160            }
 161        }
 162
 163        public void Dispose()
 164        {
 687165            CleanMarkedEntities();
 166
 687167            if (removeEntitiesCoroutine != null)
 687168                CoroutineStarter.Stop(removeEntitiesCoroutine);
 169
 687170            CommonScriptableObjects.rendererState.OnChange -= OnRendererStateChange;
 687171            Environment.i.platform.memoryManager.OnCriticalMemory -= CleanMarkedEntities;
 687172        }
 173    }
 174}