< Summary

Class:DCL.ParcelScenesCleaner
Assembly:DCL.Runtime
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/ParcelScenesCleaner.cs
Covered lines:55
Uncovered lines:15
Coverable lines:70
Total lines:172
Line coverage:78.5% (55 of 70)
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%550100%
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
 12638        Queue<IDCLEntity> entitiesMarkedForCleanup = new Queue<IDCLEntity>();
 12639        Queue<MarkedEntityInfo> rootEntitiesMarkedForCleanup = new Queue<MarkedEntityInfo>();
 12640        Queue<MarkedSharedComponentInfo> disposableComponentsMarkedForCleanup = new Queue<MarkedSharedComponentInfo>();
 41
 42        Coroutine removeEntitiesCoroutine;
 43
 44        public void Initialize ()
 45        {
 12646            removeEntitiesCoroutine = CoroutineStarter.Start(CleanupEntitiesCoroutine());
 12647            CommonScriptableObjects.rendererState.OnChange += OnRendererStateChange;
 12648        }
 49
 50        private void OnRendererStateChange(bool isEnable, bool prevState)
 51        {
 1252            if (!isEnable)
 53            {
 1254                CleanMarkedEntities();
 1255                Resources.UnloadUnusedAssets();
 56            }
 1257        }
 58
 59        public void MarkForCleanup(IDCLEntity entity)
 60        {
 161            if (entity.markedForCleanup)
 062                return;
 63
 164            entity.markedForCleanup = true;
 65
 166            if (entity.gameObject != null)
 167                entity.gameObject.SetActive(false);
 68
 69#if UNITY_EDITOR
 170            if (entity.gameObject != null)
 171                entity.gameObject.name += "-MARKED-FOR-CLEANUP";
 72#endif
 73
 174            entitiesMarkedForCleanup.Enqueue(entity);
 175        }
 76
 77        // When removing all entities from a scene, we need to separate the root entities, as stated in ParcelScene,
 78        // to avoid traversing a lot of child entities in the same frame and other problems
 279        public void MarkRootEntityForCleanup(IParcelScene scene, IDCLEntity entity) { rootEntitiesMarkedForCleanup.Enque
 80
 18081        public void MarkDisposableComponentForCleanup(IParcelScene scene, string componentId) { disposableComponentsMark
 82
 83        public void CleanMarkedEntities()
 84        {
 13885            CleanMarkedEntitiesAsync(true).MoveNext();
 13886        }
 87
 88        public IEnumerator CleanMarkedEntitiesAsync(bool immediate = false)
 89        {
 94590            float lastTime = Time.unscaledTime;
 91
 103292            while (disposableComponentsMarkedForCleanup.Count > 0)
 93            {
 8794                MarkedSharedComponentInfo markedSharedComponentInfo = disposableComponentsMarkedForCleanup.Dequeue();
 8795                markedSharedComponentInfo.scene.componentsManagerLegacy.SceneSharedComponentDispose(markedSharedComponen
 96
 8797                if (DCLTime.realtimeSinceStartup - lastTime >= MAX_TIME_BUDGET && !immediate)
 98                {
 099                    yield return null;
 0100                    lastTime = Time.unscaledTime;
 101                }
 102            }
 103
 945104            HashSet<ParcelScene> scenesToRemove = new HashSet<ParcelScene>();
 105
 106            // If we have root entities queued for removal, we call Parcel Scene's RemoveEntity()
 107            // so that the child entities end up recursively in the entitiesMarkedForCleanup queue
 946108            while (rootEntitiesMarkedForCleanup.Count > 0)
 109            {
 1110                MarkedEntityInfo markedEntityInfo = rootEntitiesMarkedForCleanup.Dequeue();
 1111                markedEntityInfo.scene.RemoveEntity(markedEntityInfo.entity.entityId, false);
 112
 1113                if (!scenesToRemove.Contains(markedEntityInfo.scene))
 1114                    scenesToRemove.Add(markedEntityInfo.scene);
 115
 1116                if (!immediate && DCLTime.realtimeSinceStartup - lastTime >= MAX_TIME_BUDGET)
 117                {
 0118                    yield return null;
 0119                    lastTime = Time.unscaledTime;
 120                }
 121            }
 122
 946123            while (entitiesMarkedForCleanup.Count > 0)
 124            {
 1125                IDCLEntity entity = entitiesMarkedForCleanup.Dequeue();
 1126                entity.SetParent(null);
 1127                entity.Cleanup();
 128
 1129                if (!immediate && DCLTime.realtimeSinceStartup - lastTime >= MAX_TIME_BUDGET)
 130                {
 0131                    yield return null;
 0132                    lastTime = Time.unscaledTime;
 133                }
 134            }
 135
 1892136            foreach (var scene in scenesToRemove)
 137            {
 1138                if (scene != null && !Environment.i.world.state.ContainsScene(scene.sceneData.id))
 1139                    Object.Destroy(scene.gameObject);
 140
 1141                if (!immediate && DCLTime.realtimeSinceStartup - lastTime >= MAX_TIME_BUDGET)
 142                {
 0143                    yield return null;
 0144                    lastTime = Time.unscaledTime;
 145                }
 146            }
 945147        }
 148
 149        IEnumerator CleanupEntitiesCoroutine()
 150        {
 126151            yield return null;
 125152            Environment.i.platform.memoryManager.OnCriticalMemory += CleanMarkedEntities;
 153
 682154            while (true)
 155            {
 807156                yield return CleanMarkedEntitiesAsync();
 736157                yield return null;
 158            }
 159        }
 160
 161        public void Dispose()
 162        {
 126163            CleanMarkedEntities();
 164
 126165            if (removeEntitiesCoroutine != null)
 126166                CoroutineStarter.Stop(removeEntitiesCoroutine);
 167
 126168            CommonScriptableObjects.rendererState.OnChange -= OnRendererStateChange;
 126169            Environment.i.platform.memoryManager.OnCriticalMemory -= CleanMarkedEntities;
 126170        }
 171    }
 172}