< Summary

Class:DCL.AssetPromise_AB_GameObject
Assembly:AssetPromiseKeeper
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/AssetManager/AssetBundles/AB_GameObject/AssetPromise_AB_GameObject.cs
Covered lines:95
Uncovered lines:20
Coverable lines:115
Total lines:261
Line coverage:82.6% (95 of 115)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
AssetPromise_AB_GameObject(...)0%110100%
OnFeatureFlagChange(...)0%110100%
OnLoad(...)0%110100%
AddToLibrary()0%3.033085.71%
OnReuse(...)0%110100%
OnAfterLoadOrReuse()0%110100%
OnBeforeLoadOrReuse()0%110100%
OnCancelLoading()0%330100%
ToString()0%6200%
LoadingCoroutine()0%11110100%
InstantiateABGameObjects()0%11.0311093.55%
UploadMeshesToGPU(...)0%330100%
GetAsset(...)0%220100%
OnForget()0%110100%
SetMaterialTransition()0%30.777021.43%
IsTransitionFinished(...)0%12300%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/AssetManager/AssetBundles/AB_GameObject/AssetPromise_AB_GameObject.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Linq;
 4using DCL.Helpers;
 5using UnityEngine;
 6using System.Collections.Generic;
 7using DCL.Models;
 8using MainScripts.DCL.Analytics.PerformanceAnalytics;
 9
 10namespace DCL
 11{
 12    public class AssetPromise_AB_GameObject : AssetPromise_WithUrl<Asset_AB_GameObject>
 13    {
 4414        public AssetPromiseSettings_Rendering settings = new AssetPromiseSettings_Rendering();
 15        AssetPromise_AB subPromise;
 16        Coroutine loadingCoroutine;
 17
 12018        private BaseVariable<FeatureFlag> featureFlags => DataStore.i.featureFlags.flags;
 19        private const string AB_LOAD_ANIMATION = "ab_load_animation";
 20        private bool doTransitionAnimation;
 21
 4422        public AssetPromise_AB_GameObject(string contentUrl, string hash) : base(contentUrl, hash)
 23        {
 4424            featureFlags.OnChange += OnFeatureFlagChange;
 4425            OnFeatureFlagChange(featureFlags.Get(), null);
 4426        }
 27
 36828        private void OnFeatureFlagChange(FeatureFlag current, FeatureFlag previous) { doTransitionAnimation = current.Is
 29
 3830        protected override void OnLoad(Action OnSuccess, Action<Exception> OnFail) { loadingCoroutine = CoroutineStarter
 31
 32        protected override bool AddToLibrary()
 33        {
 1234            if (!library.Add(asset))
 35            {
 036                return false;
 37            }
 38
 1239            if (settings.forceNewInstance)
 40            {
 241                asset = (library as AssetLibrary_AB_GameObject).GetCopyFromOriginal(asset.id);
 42            }
 43            else
 44            {
 1045                asset = library.Get(asset.id);
 46            }
 47
 48            //NOTE(Brian): Call again this method because we are replacing the asset.
 1249            settings.ApplyBeforeLoad(asset.container.transform);
 50
 1251            return true;
 52        }
 53
 54        protected override void OnReuse(Action OnSuccess)
 55        {
 2556            asset.renderers = MeshesInfoUtils.ExtractUniqueRenderers(asset.container);
 2557            asset.Show(OnSuccess);
 2558        }
 59
 60        protected override void OnAfterLoadOrReuse()
 61        {
 3762            asset.renderers = MeshesInfoUtils.ExtractUniqueRenderers(asset.container);
 3763            settings.ApplyAfterLoad(asset.container.transform);
 3764        }
 65
 8866        protected override void OnBeforeLoadOrReuse() { settings.ApplyBeforeLoad(asset.container.transform); }
 67
 68        protected override void OnCancelLoading()
 69        {
 770            if (loadingCoroutine != null)
 71            {
 372                PerformanceAnalytics.ABTracker.TrackCancelled();
 373                CoroutineStarter.Stop(loadingCoroutine);
 374                loadingCoroutine = null;
 75            }
 76
 777            if (asset != null)
 778                UnityEngine.Object.Destroy(asset.container);
 79
 780            AssetPromiseKeeper_AB.i.Forget(subPromise);
 781        }
 82
 83        public override string ToString()
 84        {
 085            if (subPromise != null)
 086                return $"{subPromise.ToString()} ... AB_GameObject state = {state}";
 87            else
 088                return $"subPromise == null? state = {state}";
 89        }
 90
 91        public IEnumerator LoadingCoroutine(Action OnSuccess, Action<Exception> OnFail)
 92        {
 1993            PerformanceAnalytics.ABTracker.TrackLoading();
 1994            subPromise = new AssetPromise_AB(contentUrl, hash, asset.container.transform);
 1995            bool success = false;
 1996            Exception loadingException = null;
 3497            subPromise.OnSuccessEvent += (x) => success = true;
 98
 1999            subPromise.OnFailEvent += ( ab,  exception) =>
 100            {
 1101                loadingException = exception;
 1102                success = false;
 1103            };
 104
 19105            asset.ownerPromise = subPromise;
 19106            AssetPromiseKeeper_AB.i.Keep(subPromise);
 107
 19108            yield return subPromise;
 109
 16110            if (success)
 111            {
 15112                yield return InstantiateABGameObjects();
 113
 15114                if (subPromise.asset == null || asset.container == null)
 3115                    success = false;
 116            }
 117
 16118            loadingCoroutine = null;
 119
 16120            if (success)
 121            {
 12122                PerformanceAnalytics.ABTracker.TrackLoaded();
 12123                OnSuccess?.Invoke();
 124            }
 125            else
 126            {
 4127                PerformanceAnalytics.ABTracker.TrackFailed();
 4128                loadingException ??= new Exception($"AB sub-promise asset or container is null. Asset: {subPromise.asset
 4129                OnFail?.Invoke(loadingException);
 130            }
 16131        }
 132
 133        private IEnumerator InstantiateABGameObjects()
 134        {
 15135            var goList = subPromise.asset.GetAssetsByExtensions<GameObject>("glb", "ltf");
 136
 15137            if (goList.Count == 0)
 138            {
 2139                if (asset.container != null)
 2140                    UnityEngine.Object.Destroy(asset.container);
 141
 2142                asset.container = null;
 143
 2144                AssetPromiseKeeper_AB.i.Forget(subPromise);
 145
 2146                yield break;
 147            }
 148
 50149            for (int i = 0; i < goList.Count; i++)
 150            {
 13151                if (loadingCoroutine == null)
 152                    break;
 153
 13154                if (asset.container == null)
 155                    break;
 156
 12157                GameObject assetBundleModelGO = UnityEngine.Object.Instantiate(goList[i], asset.container.transform);
 158
 12159                asset.renderers = MeshesInfoUtils.ExtractUniqueRenderers(assetBundleModelGO);
 12160                asset.materials = MeshesInfoUtils.ExtractUniqueMaterials(asset.renderers);
 12161                asset.SetTextures(MeshesInfoUtils.ExtractUniqueTextures(asset.materials));
 162
 12163                UploadMeshesToGPU(MeshesInfoUtils.ExtractUniqueMeshes(asset.renderers));
 12164                asset.totalTriangleCount = MeshesInfoUtils.ComputeTotalTriangles(asset.renderers, asset.meshToTriangleCo
 165
 166                //NOTE(Brian): Renderers are enabled in settings.ApplyAfterLoad
 12167                yield return MaterialCachingHelper.Process(asset.renderers.ToList(), enableRenderers: false, settings.ca
 168
 12169                var animators = MeshesInfoUtils.ExtractUniqueAnimations(assetBundleModelGO);
 12170                asset.animationClipSize = subPromise.asset.metrics.animationsEstimatedSize;
 12171                asset.meshDataSize = subPromise.asset.metrics.meshesEstimatedSize;
 172
 24173                foreach (var animator in animators)
 174                {
 0175                    animator.cullingType = AnimationCullingType.AlwaysAnimate;
 176                }
 177
 178#if UNITY_EDITOR
 12179                assetBundleModelGO.name = subPromise.asset.GetName();
 180#endif
 181
 12182                yield return null;
 183
 12184                yield return SetMaterialTransition();
 12185            }
 13186        }
 187
 188        private void UploadMeshesToGPU(HashSet<Mesh> meshesList)
 189        {
 48190            foreach ( Mesh mesh in meshesList )
 191            {
 12192                if ( !mesh.isReadable )
 193                    continue;
 194
 12195                asset.meshToTriangleCount[mesh] = mesh.triangles.Length;
 12196                asset.meshes.Add(mesh);
 197
 12198                Physics.BakeMesh(mesh.GetInstanceID(), false);
 12199                mesh.UploadMeshData(true);
 200            }
 12201        }
 202
 203        protected override Asset_AB_GameObject GetAsset(object id)
 204        {
 25205            if (settings.forceNewInstance)
 206            {
 9207                return ((AssetLibrary_AB_GameObject) library).GetCopyFromOriginal(id);
 208            }
 209            else
 210            {
 16211                return base.GetAsset(id);
 212            }
 213        }
 214
 215        internal override void OnForget()
 216        {
 32217            base.OnForget();
 32218            featureFlags.OnChange -= OnFeatureFlagChange;
 32219        }
 220
 221        IEnumerator SetMaterialTransition(Action OnSuccess = null)
 222        {
 12223            if (settings.visibleFlags != AssetPromiseSettings_Rendering.VisibleFlags.INVISIBLE && doTransitionAnimation)
 224            {
 0225                MaterialTransitionController[] materialTransitionControllers = new MaterialTransitionController[asset.re
 0226                int index = 0;
 0227                foreach (Renderer assetRenderer in asset.renderers)
 228                {
 0229                    MaterialTransitionController transition = assetRenderer.gameObject.AddComponent<MaterialTransitionCo
 0230                    materialTransitionControllers[index] = transition;
 0231                    transition.delay = 0;
 0232                    transition.OnDidFinishLoading(assetRenderer.sharedMaterial);
 233
 0234                    index++;
 235                }
 236                // Wait until MaterialTransitionController finishes its effect
 0237                yield return new WaitUntil(() => IsTransitionFinished(materialTransitionControllers));
 238            }
 12239            OnSuccess?.Invoke();
 12240        }
 241
 242        private bool IsTransitionFinished(MaterialTransitionController[] matTransitions)
 243        {
 0244            bool finishedTransition = true;
 245
 0246            for (int i = 0; i < matTransitions.Length; i++)
 247            {
 0248                if (matTransitions[i] != null)
 249                {
 0250                    finishedTransition = false;
 251
 0252                    break;
 253                }
 254            }
 255
 0256            return finishedTransition;
 257        }
 258
 259    }
 260
 261}