< Summary

Class:DCL.Components.RendereableAssetLoadHelper
Assembly:RendereableAssetLoadHelper
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Helpers/RendereableAssetLoadHelper/RendereableAssetLoadHelper.cs
Covered lines:76
Uncovered lines:53
Coverable lines:129
Total lines:332
Line coverage:58.9% (76 of 129)
Covered branches:0
Total branches:0
Covered methods:15
Total methods:19
Method coverage:78.9% (15 of 19)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
RendereableAssetLoadHelper(...)0%110100%
get_Promise()0%7.237083.33%
ToString()0%6200%
Load(...)0%6.296080%
Unload()0%110100%
UnloadAB()0%3.583060%
UnloadGLTFast()0%220100%
LoadAssetBundle(...)0%11.388062.5%
FetchAssetBundlesManifest(...)0%12300%
LoadAssetBundles(...)0%2100%
LoadGLTFast(...)0%4.014092.31%
OnFailWrapper(...)0%5.035088.89%
OnSuccessWrapper(...)0%4.594066.67%
ClearEvents()0%110100%
SendMetric(...)0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Helpers/RendereableAssetLoadHelper/RendereableAssetLoadHelper.cs

#LineLine coverage
 1using Cysharp.Threading.Tasks;
 2using MainScripts.DCL.Controllers.AssetManager.AssetBundles.SceneAB;
 3using System;
 4using System.Collections;
 5using System.Collections.Generic;
 6using UnityEngine;
 7using UnityEngine.Assertions;
 8
 9namespace DCL.Components
 10{
 11    public class RendereableAssetLoadHelper
 12    {
 13        private const string NEW_CDN_FF = "ab-new-cdn";
 14
 15        public event Action<Rendereable> OnSuccessEvent;
 16        public event Action<Exception> OnFailEvent;
 17
 18        public enum LoadingType
 19        {
 20            ASSET_BUNDLE_WITH_GLTF_FALLBACK,
 21            ASSET_BUNDLE_ONLY,
 22            GLTF_ONLY,
 23            DEFAULT
 24        }
 25
 26        private const string AB_GO_NAME_PREFIX = "AB:";
 27        private const string GLTFAST_GO_NAME_PREFIX = "GLTFast:";
 28        private const string FROM_ASSET_BUNDLE_TAG = "FromAssetBundle";
 29        private const string FROM_RAW_GLTF_TAG = "FromRawGLTF";
 30
 31        public static bool VERBOSE = false;
 32        public static bool useCustomContentServerUrl = false;
 33        public static string customContentServerUrl;
 34        public static LoadingType defaultLoadingType = LoadingType.ASSET_BUNDLE_WITH_GLTF_FALLBACK;
 35
 9536        public AssetPromiseSettings_Rendering settings = new ();
 28737        public Rendereable loadedAsset { get; protected set; }
 38
 39        private readonly string bundlesContentUrl;
 40        private readonly ContentProvider contentProvider;
 41        private AssetPromise_GLTFast_Instance gltfastPromise;
 42        private AssetPromise_AB_GameObject abPromise;
 43        private AssetPromise_SceneAB sceneABPromise;
 44        private string currentLoadingSystem;
 9745        private FeatureFlag featureFlags => DataStore.i.featureFlags.flags.Get();
 46        private string targetUrl;
 47
 48        public IEnumerator Promise
 49        {
 50            get
 51            {
 4252                if (gltfastPromise != null)
 4153                    yield return gltfastPromise;
 54
 4255                if (abPromise != null)
 056                    yield return abPromise;
 57
 4258                yield return null;
 4259            }
 60        }
 61
 62        public bool IsFinished
 63        {
 64            get
 65            {
 166                if (gltfastPromise != null)
 167                    return gltfastPromise.state == AssetPromiseState.FINISHED;
 68
 069                if (abPromise != null)
 070                    return abPromise.state == AssetPromiseState.FINISHED;
 71
 072                return false;
 73            }
 74        }
 75
 76#if UNITY_EDITOR
 77        public override string ToString()
 78        {
 079            float loadTime = Mathf.Min(loadFinishTime, Time.realtimeSinceStartup) - loadStartTime;
 80
 081            string result = "not loading";
 82
 083            if (abPromise != null) { result = $"ASSET BUNDLE -> promise state = {abPromise.ToString()} ({loadTime} load 
 84
 085            return result;
 86        }
 87
 88        float loadStartTime = 0;
 9589        float loadFinishTime = float.MaxValue;
 90#endif
 91
 9592        public RendereableAssetLoadHelper(ContentProvider contentProvider, string bundlesContentUrl)
 93        {
 9594            this.contentProvider = contentProvider;
 9595            this.bundlesContentUrl = bundlesContentUrl;
 9596        }
 97
 98        public void Load(string targetUrl, LoadingType forcedLoadingType = LoadingType.DEFAULT)
 99        {
 100100            this.targetUrl = targetUrl;
 100101            Assert.IsFalse(string.IsNullOrEmpty(targetUrl), "url is null!!");
 102#if UNITY_EDITOR
 100103            loadStartTime = Time.realtimeSinceStartup;
 104#endif
 100105            LoadingType finalLoadingType = forcedLoadingType == LoadingType.DEFAULT ? defaultLoadingType : forcedLoading
 106
 107            switch (finalLoadingType)
 108            {
 109                case LoadingType.ASSET_BUNDLE_ONLY:
 0110                    LoadAssetBundle(targetUrl, OnSuccessEvent, OnFailEvent, false);
 0111                    break;
 112                case LoadingType.GLTF_ONLY:
 2113                    LoadGLTFast(targetUrl, OnSuccessEvent, OnFailEvent, false);
 2114                    break;
 115                case LoadingType.DEFAULT:
 116                case LoadingType.ASSET_BUNDLE_WITH_GLTF_FALLBACK:
 196117                    LoadAssetBundle(targetUrl, OnSuccessEvent, exception => LoadGLTFast(targetUrl, OnSuccessEvent, OnFai
 118                    break;
 119            }
 98120        }
 121
 122        public void Unload()
 123        {
 64124            UnloadAB();
 64125            UnloadGLTFast();
 64126        }
 127
 128        void UnloadAB()
 129        {
 64130            if (abPromise != null) { AssetPromiseKeeper_AB_GameObject.i.Forget(abPromise); }
 131
 64132            if (sceneABPromise != null) { AssetPromiseKeeper_SceneAB.i.Forget(sceneABPromise); }
 64133        }
 134
 135        void UnloadGLTFast()
 136        {
 141137            if (gltfastPromise != null) { AssetPromiseKeeper_GLTFast_Instance.i.Forget(gltfastPromise); }
 71138        }
 139
 140        private void LoadAssetBundle(string targetUrl, Action<Rendereable> OnSuccess, Action<Exception> OnFail, bool has
 141        {
 98142            currentLoadingSystem = AB_GO_NAME_PREFIX;
 143
 98144            if (abPromise != null)
 145            {
 0146                UnloadAB();
 147
 0148                if (VERBOSE)
 0149                    Debug.Log("Forgetting not null promise..." + targetUrl);
 150            }
 151
 98152            if (!contentProvider.TryGetContentsUrl_Raw(targetUrl, out string hash))
 153            {
 1154                OnFailWrapper(OnFail, new Exception($"Content url does not contains {targetUrl}"), hasFallback);
 1155                return;
 156            }
 157
 97158            if (featureFlags.IsFeatureEnabled(NEW_CDN_FF))
 159            {
 0160                FetchAssetBundlesManifest(OnSuccess, OnFail, hasFallback, hash);
 161            }
 162            else
 163            {
 97164                string bundlesBaseUrl = useCustomContentServerUrl ? customContentServerUrl : bundlesContentUrl;
 165
 97166                if (string.IsNullOrEmpty(bundlesBaseUrl))
 167                {
 97168                    OnFailWrapper(OnFail, new Exception("bundlesBaseUrl is null"), hasFallback);
 97169                    return;
 170                }
 171
 0172                LoadAssetBundles(OnSuccess, OnFail, hasFallback, bundlesBaseUrl, hash);
 173            }
 0174        }
 175
 176        private void FetchAssetBundlesManifest(Action<Rendereable> onSuccess, Action<Exception> onFail, bool hasFallback
 177        {
 0178            if (contentProvider.assetBundles.Contains(hash))
 0179                LoadAssetBundles(onSuccess, onFail, hasFallback, contentProvider.assetBundlesBaseUrl, hash);
 180            else
 181            {
 0182                if (contentProvider.assetBundlesFetched)
 183                {
 0184                    OnFailWrapper(onFail, new Exception("Asset not converted to asset bundles"), hasFallback);
 0185                    return;
 186                }
 187
 0188                sceneABPromise = new AssetPromise_SceneAB(contentProvider.baseUrlBundles, contentProvider.sceneCid);
 0189                sceneABPromise.OnSuccessEvent += ab =>
 190                {
 0191                    if (ab.IsSceneConverted())
 192                    {
 0193                        contentProvider.assetBundles = ab.GetConvertedFiles();
 0194                        contentProvider.assetBundlesBaseUrl = ab.GetBaseUrl();
 0195                        contentProvider.assetBundlesVersion = ab.GetVersion();
 0196                        LoadAssetBundles(onSuccess, onFail, hasFallback, contentProvider.assetBundlesBaseUrl, hash);
 197                    }
 0198                    else { OnFailWrapper(onFail, new Exception("Asset not converted to asset bundles"), hasFallback); }
 199
 0200                    contentProvider.assetBundlesFetched = true;
 0201                };
 202
 0203                sceneABPromise.OnFailEvent += (_, exception) => { OnFailWrapper(onFail, exception, hasFallback); };
 204
 0205                AssetPromiseKeeper_SceneAB.i.Keep(sceneABPromise);
 206            }
 0207        }
 208
 209        private void LoadAssetBundles(Action<Rendereable> OnSuccess, Action<Exception> OnFail, bool hasFallback, string 
 210        {
 0211            abPromise = new AssetPromise_AB_GameObject(bundlesBaseUrl, hash);
 0212            abPromise.settings = this.settings;
 213
 0214            abPromise.OnSuccessEvent += (x) =>
 215            {
 216#if UNITY_EDITOR
 0217                x.container.name = AB_GO_NAME_PREFIX + hash + " - " + contentProvider.assetBundlesVersion;
 218#endif
 0219                var r = new Rendereable()
 220                {
 221                    container = x.container,
 222                    totalTriangleCount = x.totalTriangleCount,
 223                    meshes = x.meshes,
 224                    renderers = x.renderers,
 225                    materials = x.materials,
 226                    textures = x.textures,
 227                    meshToTriangleCount = x.meshToTriangleCount,
 228                    animationClipSize = x.animationClipSize,
 229                    animationClips = x.animationClips,
 230                    meshDataSize = x.meshDataSize
 231                };
 232
 0233                foreach (var someRenderer in r.renderers)
 0234                    someRenderer.tag = FROM_ASSET_BUNDLE_TAG;
 235
 0236                OnSuccessWrapper(r, OnSuccess);
 0237            };
 238
 0239            abPromise.OnFailEvent += (x, exception) => OnFailWrapper(OnFail, exception, hasFallback);
 240
 0241            AssetPromiseKeeper_AB_GameObject.i.Keep(abPromise);
 0242        }
 243
 244        private void LoadGLTFast(string targetUrl, Action<Rendereable> OnSuccess, Action<Exception> OnFail, bool hasFall
 245        {
 100246            currentLoadingSystem = GLTFAST_GO_NAME_PREFIX;
 247
 100248            if (gltfastPromise != null)
 249            {
 7250                UnloadGLTFast();
 251
 7252                if (VERBOSE)
 0253                    Debug.Log("Forgetting not null promise... " + targetUrl);
 254            }
 255
 100256            if (!contentProvider.TryGetContentsUrl_Raw(targetUrl, out string hash))
 257            {
 1258                OnFailWrapper(OnFail, new Exception($"Content provider does not contains url {targetUrl}"), hasFallback)
 1259                return;
 260            }
 261
 99262            gltfastPromise = new AssetPromise_GLTFast_Instance(targetUrl, hash,
 263                Environment.i.platform.webRequest, contentProvider, settings);
 264
 99265            gltfastPromise.OnSuccessEvent += (Asset_GLTFast_Instance x) =>
 266            {
 267#if UNITY_EDITOR
 90268                x.container.name = GLTFAST_GO_NAME_PREFIX + hash;
 269#endif
 90270                Rendereable r = x.ToRendereable();
 271
 492272                foreach (var someRenderer in r.renderers)
 156273                    someRenderer.tag = FROM_RAW_GLTF_TAG;
 274
 90275                OnSuccessWrapper(r, OnSuccess);
 90276            };
 277
 99278            gltfastPromise.OnFailEvent += (asset, exception) => { OnFailWrapper(OnFail, exception, hasFallback); };
 279
 99280            AssetPromiseKeeper_GLTFast_Instance.i.Keep(gltfastPromise);
 99281        }
 282
 283        private void OnFailWrapper(Action<Exception> OnFail, Exception exception, bool hasFallback)
 284        {
 285#if UNITY_EDITOR
 99286            loadFinishTime = Time.realtimeSinceStartup;
 287#endif
 288
 289            // If the entity is destroyed while loading, the exception is expected to be null and no error should be thr
 99290            if (exception != null)
 291            {
 99292                if (!hasFallback)
 1293                    Debug.LogWarning("All fallbacks failed for " + targetUrl);
 98294                else if (VERBOSE)
 0295                    Debug.LogWarning($"Load Fail Detected, trying to use a fallback, " +
 296                                     $"loading type was: {currentLoadingSystem} and error was: {exception.Message}");
 297            }
 298
 99299            OnFail?.Invoke(exception);
 99300            ClearEvents();
 99301        }
 302
 303        private void OnSuccessWrapper(Rendereable loadedAsset, Action<Rendereable> OnSuccess)
 304        {
 305#if UNITY_EDITOR
 90306            loadFinishTime = Time.realtimeSinceStartup;
 307#endif
 90308            if (VERBOSE)
 309            {
 0310                if (gltfastPromise != null)
 0311                    Debug.Log($"GLTF Load(): target URL -> {gltfastPromise.GetId()}. Success!");
 312                else
 0313                    Debug.Log($"AB Load(): target URL -> {abPromise.hash}. Success!");
 314            }
 315
 90316            this.loadedAsset = loadedAsset;
 90317            OnSuccess?.Invoke(loadedAsset);
 90318            ClearEvents();
 90319        }
 320
 321        public void ClearEvents()
 322        {
 210323            OnSuccessEvent = null;
 210324            OnFailEvent = null;
 210325        }
 326
 327        private void SendMetric(string eventToSend, string targetUrl, string reason)
 328        {
 0329            GenericAnalytics.SendAnalytic(eventToSend, new Dictionary<string, string> { { "targetUrl", targetUrl }, { "r
 0330        }
 331    }
 332}