< 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:63
Uncovered lines:21
Coverable lines:84
Total lines:210
Line coverage:75% (63 of 84)
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%13130100%
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 UnityEngine;
 6
 7namespace DCL
 8{
 9    public class AssetBundlesLoader
 10    {
 11        private const float MAX_LOAD_BUDGET_TIME = 0.05f;
 12        private const int SKIPPED_FRAMES_AFTER_BUDGET_TIME_IS_REACHED_FOR_NEARBY_ASSETS = 1;
 13        private const int SKIPPED_FRAMES_AFTER_BUDGET_TIME_IS_REACHED_FOR_DISTANT_ASSETS = 5;
 14        private const float MAX_SQR_DISTANCE_FOR_QUICK_LOADING = 6000f;
 15        private const float TIME_BETWEEN_REPRIORITIZATIONS = 1f;
 16
 17        private struct AssetBundleInfo
 18        {
 19            public Asset_AB asset;
 20            public Transform containerTransform;
 21            public Action onSuccess;
 22            public Action<Exception> onFail;
 23
 24            public AssetBundleInfo(Asset_AB asset, Transform containerTransform, Action onSuccess, Action<Exception> onF
 25            {
 2326                this.asset = asset;
 2327                this.containerTransform = containerTransform;
 2328                this.onSuccess = onSuccess;
 2329                this.onFail = onFail;
 2330            }
 31        }
 32
 33        private Coroutine assetBundlesLoadingCoroutine;
 134        private Queue<AssetBundleInfo> highPriorityLoadQueue = new Queue<AssetBundleInfo>();
 135        private Queue<AssetBundleInfo> lowPriorityLoadQueue = new Queue<AssetBundleInfo>();
 36
 137        private Dictionary<string, int> loadOrderByExtension = new Dictionary<string, int>()
 38        {
 39            { "png", 0 },
 40            { "jpg", 1 },
 41            { "peg", 2 },
 42            { "bmp", 3 },
 43            { "psd", 4 },
 44            { "iff", 5 },
 45            { "mat", 6 },
 46            { "nim", 7 },
 47            { "ltf", 8 },
 48            { "glb", 9 }
 49        };
 50
 151        private List<UnityEngine.Object> loadedAssetsByName = new List<UnityEngine.Object>();
 52        private float currentLoadBudgetTime = 0;
 53        private AssetBundleInfo assetBundleInfoToLoad;
 54        private float lastQueuesReprioritizationTime = 0;
 55
 4156        private bool limitTimeBudget => CommonScriptableObjects.rendererState.Get();
 57
 58        public void Start()
 59        {
 4460            if (assetBundlesLoadingCoroutine != null)
 3861                return;
 62
 663            assetBundlesLoadingCoroutine = CoroutineStarter.Start(LoadAssetBundlesCoroutine());
 664        }
 65
 66        public void Stop()
 67        {
 3568            if (assetBundlesLoadingCoroutine == null)
 2969                return;
 70
 671            CoroutineStarter.Stop(assetBundlesLoadingCoroutine);
 672            assetBundlesLoadingCoroutine = null;
 73
 674            highPriorityLoadQueue.Clear();
 675            lowPriorityLoadQueue.Clear();
 676        }
 77
 78        public void MarkAssetBundleForLoad(Asset_AB asset, Transform containerTransform, Action onSuccess, Action<Except
 79        {
 2380            CheckForReprioritizeAwaitingAssets();
 81
 2382            AssetBundleInfo assetBundleToLoad = new AssetBundleInfo(asset, containerTransform, onSuccess, onFail);
 83
 2384            float distanceFromPlayer = GetDistanceFromPlayer(containerTransform);
 2385            if (distanceFromPlayer <= MAX_SQR_DISTANCE_FOR_QUICK_LOADING)
 2386                highPriorityLoadQueue.Enqueue(assetBundleToLoad);
 87            else
 088                lowPriorityLoadQueue.Enqueue(assetBundleToLoad);
 089        }
 90
 91        private IEnumerator LoadAssetBundlesCoroutine()
 92        {
 26793            while (true)
 94            {
 29695                while (highPriorityLoadQueue.Count > 0)
 96                {
 2397                    float time = Time.realtimeSinceStartup;
 98
 2399                    assetBundleInfoToLoad = highPriorityLoadQueue.Dequeue();
 23100                    yield return LoadAssetBundle(assetBundleInfoToLoad);
 101
 23102                    if (IsLoadBudgetTimeReached(time))
 103                    {
 0104                        yield return WaitForSkippedFrames(SKIPPED_FRAMES_AFTER_BUDGET_TIME_IS_REACHED_FOR_NEARBY_ASSETS)
 0105                        time = Time.realtimeSinceStartup;
 106                    }
 107                }
 108
 273109                while (lowPriorityLoadQueue.Count > 0 && highPriorityLoadQueue.Count == 0)
 110                {
 0111                    float time = Time.realtimeSinceStartup;
 112
 0113                    assetBundleInfoToLoad = lowPriorityLoadQueue.Dequeue();
 0114                    yield return LoadAssetBundle(assetBundleInfoToLoad);
 115
 0116                    if (IsLoadBudgetTimeReached(time))
 117                    {
 0118                        yield return WaitForSkippedFrames(SKIPPED_FRAMES_AFTER_BUDGET_TIME_IS_REACHED_FOR_DISTANT_ASSETS
 0119                        time = Time.realtimeSinceStartup;
 120                    }
 121                }
 122
 273123                yield return null;
 124            }
 125        }
 126
 127        private IEnumerator LoadAssetBundle(AssetBundleInfo assetBundleInfo)
 128        {
 23129            if (!assetBundleInfo.asset.IsValid())
 130            {
 1131                assetBundleInfo.onFail?.Invoke(new Exception("Asset bundle is null"));
 1132                yield break;
 133            }
 134
 22135            AssetBundleRequest abRequest = assetBundleInfo.asset.LoadAllAssetsAsync();
 136
 88137            while (!abRequest.isDone)
 138            {
 66139                yield return null;
 140            }
 141
 22142            loadedAssetsByName = abRequest.allAssets.ToList();
 143
 178144            foreach (var loadedAsset in loadedAssetsByName)
 145            {
 67146                string ext = "any";
 147
 67148                if (loadedAsset is Texture)
 149                {
 7150                    ext = "png";
 7151                }
 60152                else if (loadedAsset is Material)
 153                {
 13154                    ext = "mat";
 13155                }
 47156                else if (loadedAsset is Animation || loadedAsset is AnimationClip)
 157                {
 8158                    ext = "nim";
 8159                }
 39160                else if (loadedAsset is GameObject)
 161                {
 13162                    ext = "glb";
 163                }
 164
 67165                assetBundleInfo.asset.AddAssetByExtension(ext, loadedAsset);
 166            }
 167
 22168            loadedAssetsByName.Clear();
 22169            assetBundleInfo.onSuccess?.Invoke();
 22170        }
 171
 172        private bool IsLoadBudgetTimeReached(float startTime)
 173        {
 23174            if (limitTimeBudget)
 175            {
 0176                currentLoadBudgetTime += Time.realtimeSinceStartup - startTime;
 0177                if (currentLoadBudgetTime > MAX_LOAD_BUDGET_TIME)
 178                {
 0179                    currentLoadBudgetTime = 0f;
 0180                    return true;
 181                }
 182            }
 183
 23184            return false;
 185        }
 186
 187        private IEnumerator WaitForSkippedFrames(int skippedFramesBetweenLoadings)
 188        {
 0189            for (int i = 0; i < skippedFramesBetweenLoadings; i++)
 190            {
 0191                yield return null;
 192            }
 0193        }
 194
 195        private void CheckForReprioritizeAwaitingAssets()
 196        {
 23197            if (lowPriorityLoadQueue.Count == 0 ||
 198                (Time.realtimeSinceStartup - lastQueuesReprioritizationTime) < TIME_BETWEEN_REPRIORITIZATIONS)
 23199                return;
 200
 0201            while (lowPriorityLoadQueue.Count > 0 && GetDistanceFromPlayer(lowPriorityLoadQueue.Peek().containerTransfor
 202            {
 0203                highPriorityLoadQueue.Enqueue(lowPriorityLoadQueue.Dequeue());
 0204                lastQueuesReprioritizationTime = Time.realtimeSinceStartup;
 205            }
 0206        }
 207
 23208        private float GetDistanceFromPlayer(Transform containerTransform) { return (containerTransform != null && limitT
 209    }
 210}