< Summary

Class:DCL.AssetBundlesLoader
Assembly:AssetPromiseKeeper
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/AssetManager/AssetBundles/AB/AssetBundlesLoader.cs
Covered lines:59
Uncovered lines:23
Coverable lines:82
Total lines:212
Line coverage:71.9% (59 of 82)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
AssetBundleInfo(...)0%110100%
AssetBundlesLoader()0%110100%
Start()0%220100%
Stop()0%220100%
MarkAssetBundleForLoad(...)0%2.092071.43%
LoadAssetBundlesCoroutine()0%3012050%
LoadAssetBundle()0%13.113091.67%
IsLoadBudgetTimeReached(...)0%5.673033.33%
WaitForSkippedFrames()0%20400%
CheckForReprioritizeAwaitingAssets()0%12.415033.33%
GetDistanceFromPlayer(...)0%330100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/AssetManager/AssetBundles/AB/AssetBundlesLoader.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Linq;
 5using DCL.Helpers;
 6using UnityEngine;
 7
 8namespace DCL
 9{
 10    public class AssetBundlesLoader
 11    {
 12        private const float MAX_LOAD_BUDGET_TIME = 0.05f;
 13        private const int SKIPPED_FRAMES_AFTER_BUDGET_TIME_IS_REACHED_FOR_NEARBY_ASSETS = 1;
 14        private const int SKIPPED_FRAMES_AFTER_BUDGET_TIME_IS_REACHED_FOR_DISTANT_ASSETS = 5;
 15        private const float MAX_SQR_DISTANCE_FOR_QUICK_LOADING = 6000f;
 16        private const float TIME_BETWEEN_REPRIORITIZATIONS = 1f;
 17
 18        private struct AssetBundleInfo
 19        {
 20            public Asset_AB asset;
 21            public Transform containerTransform;
 22            public Action onSuccess;
 23            public Action<Exception> onFail;
 24
 25            public AssetBundleInfo(Asset_AB asset, Transform containerTransform, Action onSuccess, Action<Exception> onF
 26            {
 2227                this.asset = asset;
 2228                this.containerTransform = containerTransform;
 2229                this.onSuccess = onSuccess;
 2230                this.onFail = onFail;
 2231            }
 32        }
 33
 34        private Coroutine assetBundlesLoadingCoroutine;
 135        private Queue<AssetBundleInfo> highPriorityLoadQueue = new Queue<AssetBundleInfo>();
 136        private Queue<AssetBundleInfo> lowPriorityLoadQueue = new Queue<AssetBundleInfo>();
 37
 138        private Dictionary<string, int> loadOrderByExtension = new Dictionary<string, int>()
 39        {
 40            { "png", 0 },
 41            { "jpg", 1 },
 42            { "peg", 2 },
 43            { "bmp", 3 },
 44            { "psd", 4 },
 45            { "iff", 5 },
 46            { "mat", 6 },
 47            { "nim", 7 },
 48            { "ltf", 8 },
 49            { "glb", 9 }
 50        };
 51
 152        private List<UnityEngine.Object> loadedAssetsByName = new List<UnityEngine.Object>();
 53        private float currentLoadBudgetTime = 0;
 54        private AssetBundleInfo assetBundleInfoToLoad;
 55        private float lastQueuesReprioritizationTime = 0;
 56
 3857        private bool limitTimeBudget => CommonScriptableObjects.rendererState.Get();
 58
 59        public void Start()
 60        {
 4361            if (assetBundlesLoadingCoroutine != null)
 3762                return;
 63
 664            assetBundlesLoadingCoroutine = CoroutineStarter.Start(LoadAssetBundlesCoroutine());
 665        }
 66
 67        public void Stop()
 68        {
 3569            if (assetBundlesLoadingCoroutine == null)
 2970                return;
 71
 672            CoroutineStarter.Stop(assetBundlesLoadingCoroutine);
 673            assetBundlesLoadingCoroutine = null;
 74
 675            highPriorityLoadQueue.Clear();
 676            lowPriorityLoadQueue.Clear();
 677        }
 78
 79        public void MarkAssetBundleForLoad(Asset_AB asset, Transform containerTransform, Action onSuccess, Action<Except
 80        {
 2281            CheckForReprioritizeAwaitingAssets();
 82
 2283            AssetBundleInfo assetBundleToLoad = new AssetBundleInfo(asset, containerTransform, onSuccess, onFail);
 84
 2285            float distanceFromPlayer = GetDistanceFromPlayer(containerTransform);
 2286            if (distanceFromPlayer <= MAX_SQR_DISTANCE_FOR_QUICK_LOADING)
 2287                highPriorityLoadQueue.Enqueue(assetBundleToLoad);
 88            else
 089                lowPriorityLoadQueue.Enqueue(assetBundleToLoad);
 090        }
 91
 92        private IEnumerator LoadAssetBundlesCoroutine()
 93        {
 205194            while (true)
 95            {
 207996                while (highPriorityLoadQueue.Count > 0)
 97                {
 2298                    float time = Time.realtimeSinceStartup;
 99
 22100                    assetBundleInfoToLoad = highPriorityLoadQueue.Dequeue();
 22101                    yield return LoadAssetBundle(assetBundleInfoToLoad);
 102
 22103                    if (IsLoadBudgetTimeReached(time))
 104                    {
 0105                        yield return WaitForSkippedFrames(SKIPPED_FRAMES_AFTER_BUDGET_TIME_IS_REACHED_FOR_NEARBY_ASSETS)
 0106                        time = Time.realtimeSinceStartup;
 107                    }
 108                }
 109
 2057110                while (lowPriorityLoadQueue.Count > 0 && highPriorityLoadQueue.Count == 0)
 111                {
 0112                    float time = Time.realtimeSinceStartup;
 113
 0114                    assetBundleInfoToLoad = lowPriorityLoadQueue.Dequeue();
 0115                    yield return LoadAssetBundle(assetBundleInfoToLoad);
 116
 0117                    if (IsLoadBudgetTimeReached(time))
 118                    {
 0119                        yield return WaitForSkippedFrames(SKIPPED_FRAMES_AFTER_BUDGET_TIME_IS_REACHED_FOR_DISTANT_ASSETS
 0120                        time = Time.realtimeSinceStartup;
 121                    }
 122                }
 123
 2057124                yield return null;
 125            }
 126        }
 127
 128        private IEnumerator LoadAssetBundle(AssetBundleInfo assetBundleInfo)
 129        {
 22130            if (!assetBundleInfo.asset.IsValid())
 131            {
 0132                assetBundleInfo.onFail?.Invoke(new Exception("Asset bundle is null"));
 0133                yield break;
 134            }
 135
 22136            AssetBundleRequest abRequest = assetBundleInfo.asset.LoadAllAssetsAsync();
 137
 1543138            while (!abRequest.isDone)
 139            {
 1521140                yield return null;
 141            }
 142
 22143            loadedAssetsByName = abRequest.allAssets.ToList();
 144
 178145            foreach (var loadedAsset in loadedAssetsByName)
 146            {
 67147                string ext = "any";
 148
 67149                if (loadedAsset is Texture)
 150                {
 7151                    ext = "png";
 152                }
 60153                else if (loadedAsset is Material material)
 154                {
 13155                    ShaderUtils.UpgradeMaterial_2020_To_2021(material);
 13156                    ext = "mat";
 157                }
 47158                else if (loadedAsset is Animation || loadedAsset is AnimationClip)
 159                {
 8160                    ext = "nim";
 161                }
 39162                else if (loadedAsset is GameObject)
 163                {
 13164                    ext = "glb";
 165                }
 166
 67167                assetBundleInfo.asset.AddAssetByExtension(ext, loadedAsset);
 168            }
 169
 22170            loadedAssetsByName.Clear();
 22171            assetBundleInfo.onSuccess?.Invoke();
 22172        }
 173
 174        private bool IsLoadBudgetTimeReached(float startTime)
 175        {
 22176            if (limitTimeBudget)
 177            {
 0178                currentLoadBudgetTime += Time.realtimeSinceStartup - startTime;
 0179                if (currentLoadBudgetTime > MAX_LOAD_BUDGET_TIME)
 180                {
 0181                    currentLoadBudgetTime = 0f;
 0182                    return true;
 183                }
 184            }
 185
 22186            return false;
 187        }
 188
 189        private IEnumerator WaitForSkippedFrames(int skippedFramesBetweenLoadings)
 190        {
 0191            for (int i = 0; i < skippedFramesBetweenLoadings; i++)
 192            {
 0193                yield return null;
 194            }
 0195        }
 196
 197        private void CheckForReprioritizeAwaitingAssets()
 198        {
 22199            if (lowPriorityLoadQueue.Count == 0 ||
 200                (Time.realtimeSinceStartup - lastQueuesReprioritizationTime) < TIME_BETWEEN_REPRIORITIZATIONS)
 22201                return;
 202
 0203            while (lowPriorityLoadQueue.Count > 0 && GetDistanceFromPlayer(lowPriorityLoadQueue.Peek().containerTransfor
 204            {
 0205                highPriorityLoadQueue.Enqueue(lowPriorityLoadQueue.Dequeue());
 0206                lastQueuesReprioritizationTime = Time.realtimeSinceStartup;
 207            }
 0208        }
 209
 22210        private float GetDistanceFromPlayer(Transform containerTransform) { return (containerTransform != null && limitT
 211    }
 212}