< 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:7
Coverable lines:102
Total lines:229
Line coverage:93.1% (95 of 102)
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.023087.5%
OnReuse(...)0%110100%
OnAfterLoadOrReuse()0%110100%
OnBeforeLoadOrReuse()0%110100%
OnCancelLoading()0%330100%
ToString()0%6200%
LoadingCoroutine()0%11110100%
InstantiateABGameObjects()0%10.0310093.55%
UploadMeshesToGPU(...)0%4.14081.82%
GetAsset(...)0%220100%
OnForget()0%110100%

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
 13218        private BaseVariable<FeatureFlag> featureFlags => DataStore.i.featureFlags.flags;
 19        private const string AB_LOAD_ANIMATION = "ab_load_animation";
 20        private const string GPU_ONLY_MESHES = "use_gpu_only_meshes";
 21        private bool doTransitionAnimation;
 22
 4423        public AssetPromise_AB_GameObject(string contentUrl, string hash) : base(contentUrl, hash)
 24        {
 4425            featureFlags.OnChange += OnFeatureFlagChange;
 4426            OnFeatureFlagChange(featureFlags.Get(), null);
 4427        }
 28
 8829        private void OnFeatureFlagChange(FeatureFlag current, FeatureFlag previous) { doTransitionAnimation = current.Is
 30
 3831        protected override void OnLoad(Action OnSuccess, Action<Exception> OnFail) { loadingCoroutine = CoroutineStarter
 32
 33        protected override bool AddToLibrary()
 34        {
 1235            if (!library.Add(asset))
 36            {
 037                return false;
 38            }
 39
 1240            if (settings.forceNewInstance)
 41            {
 242                asset = (library as AssetLibrary_AB_GameObject).GetCopyFromOriginal(asset.id);
 243            }
 44            else
 45            {
 1046                asset = library.Get(asset.id);
 47            }
 48
 49            //NOTE(Brian): Call again this method because we are replacing the asset.
 1250            settings.ApplyBeforeLoad(asset.container.transform);
 51
 1252            return true;
 53        }
 54
 55        protected override void OnReuse(Action OnSuccess)
 56        {
 2557            asset.renderers = MeshesInfoUtils.ExtractUniqueRenderers(asset.container);
 2558            asset.Show(OnSuccess);
 2559        }
 60
 61        protected override void OnAfterLoadOrReuse()
 62        {
 3763            asset.renderers = MeshesInfoUtils.ExtractUniqueRenderers(asset.container);
 3764            settings.ApplyAfterLoad(asset.container.transform);
 3765        }
 66
 8867        protected override void OnBeforeLoadOrReuse() { settings.ApplyBeforeLoad(asset.container.transform); }
 68
 69        protected override void OnCancelLoading()
 70        {
 771            if (loadingCoroutine != null)
 72            {
 373                PerformanceAnalytics.ABTracker.TrackCancelled();
 374                CoroutineStarter.Stop(loadingCoroutine);
 375                loadingCoroutine = null;
 76            }
 77
 778            if (asset != null)
 779                UnityEngine.Object.Destroy(asset.container);
 80
 781            AssetPromiseKeeper_AB.i.Forget(subPromise);
 782        }
 83
 84        public override string ToString()
 85        {
 086            if (subPromise != null)
 087                return $"{subPromise.ToString()} ... AB_GameObject state = {state}";
 88            else
 089                return $"subPromise == null? state = {state}";
 90        }
 91
 92        public IEnumerator LoadingCoroutine(Action OnSuccess, Action<Exception> OnFail)
 93        {
 1994            PerformanceAnalytics.ABTracker.TrackLoading();
 1995            subPromise = new AssetPromise_AB(contentUrl, hash, asset.container.transform);
 1996            bool success = false;
 1997            Exception loadingException = null;
 3498            subPromise.OnSuccessEvent += (x) => success = true;
 99
 19100            subPromise.OnFailEvent += ( ab,  exception) =>
 101            {
 1102                loadingException = exception;
 1103                success = false;
 1104            };
 105
 19106            asset.ownerPromise = subPromise;
 19107            AssetPromiseKeeper_AB.i.Keep(subPromise);
 108
 19109            yield return subPromise;
 110
 16111            if (success)
 112            {
 15113                yield return InstantiateABGameObjects();
 114
 15115                if (subPromise.asset == null || asset.container == null)
 3116                    success = false;
 117            }
 118
 16119            loadingCoroutine = null;
 120
 16121            if (success)
 122            {
 12123                PerformanceAnalytics.ABTracker.TrackLoaded();
 12124                OnSuccess?.Invoke();
 12125            }
 126            else
 127            {
 4128                PerformanceAnalytics.ABTracker.TrackFailed();
 4129                loadingException ??= new Exception($"AB sub-promise asset or container is null. Asset: {subPromise.asset
 4130                Debug.LogException(loadingException);
 4131                OnFail?.Invoke(loadingException);
 132            }
 16133        }
 134
 135        public IEnumerator InstantiateABGameObjects()
 136        {
 15137            var goList = subPromise.asset.GetAssetsByExtensions<GameObject>("glb", "ltf");
 138
 15139            if (goList.Count == 0)
 140            {
 2141                if (asset.container != null)
 2142                    UnityEngine.Object.Destroy(asset.container);
 143
 2144                asset.container = null;
 145
 2146                AssetPromiseKeeper_AB.i.Forget(subPromise);
 147
 2148                yield break;
 149            }
 150
 50151            for (int i = 0; i < goList.Count; i++)
 152            {
 13153                if (loadingCoroutine == null)
 154                    break;
 155
 13156                if (asset.container == null)
 157                    break;
 158
 12159                GameObject assetBundleModelGO = UnityEngine.Object.Instantiate(goList[i], asset.container.transform);
 160
 12161                asset.renderers = MeshesInfoUtils.ExtractUniqueRenderers(assetBundleModelGO);
 12162                asset.materials = MeshesInfoUtils.ExtractUniqueMaterials(asset.renderers);
 12163                asset.SetTextures(MeshesInfoUtils.ExtractUniqueTextures(asset.materials));
 164
 12165                UploadMeshesToGPU(MeshesInfoUtils.ExtractUniqueMeshes(asset.renderers));
 12166                asset.totalTriangleCount = MeshesInfoUtils.ComputeTotalTriangles(asset.renderers, asset.meshToTriangleCo
 167
 168                //NOTE(Brian): Renderers are enabled in settings.ApplyAfterLoad
 12169                yield return MaterialCachingHelper.Process(asset.renderers.ToList(), enableRenderers: false, settings.ca
 170
 12171                var animators = MeshesInfoUtils.ExtractUniqueAnimations(assetBundleModelGO);
 12172                asset.animationClipSize = subPromise.asset.metrics.animationsEstimatedSize;
 12173                asset.meshDataSize = subPromise.asset.metrics.meshesEstimatedSize;
 174
 24175                foreach (var animator in animators)
 176                {
 0177                    animator.cullingType = AnimationCullingType.AlwaysAnimate;
 178                }
 179
 180#if UNITY_EDITOR
 12181                assetBundleModelGO.name = subPromise.asset.GetName();
 182#endif
 12183                assetBundleModelGO.transform.ResetLocalTRS();
 184
 12185                yield return null;
 12186            }
 13187        }
 188
 189        private void UploadMeshesToGPU(HashSet<Mesh> meshesList)
 190        {
 12191            var uploadToGPU = featureFlags.Get().IsFeatureEnabled(GPU_ONLY_MESHES);
 192
 48193            foreach ( Mesh mesh in meshesList )
 194            {
 12195                if ( !mesh.isReadable )
 196                    continue;
 197
 12198                asset.meshToTriangleCount[mesh] = mesh.triangles.Length;
 12199                asset.meshes.Add(mesh);
 200
 12201                if (uploadToGPU)
 202                {
 0203                    Physics.BakeMesh(mesh.GetInstanceID(), false);
 0204                    mesh.UploadMeshData(true);
 205                }
 206            }
 12207        }
 208
 209        protected override Asset_AB_GameObject GetAsset(object id)
 210        {
 25211            if (settings.forceNewInstance)
 212            {
 9213                return ((AssetLibrary_AB_GameObject) library).GetCopyFromOriginal(id);
 214            }
 215            else
 216            {
 16217                return base.GetAsset(id);
 218            }
 219        }
 220
 221        internal override void OnForget()
 222        {
 32223            base.OnForget();
 32224            featureFlags.OnChange -= OnFeatureFlagChange;
 32225        }
 226
 227    }
 228
 229}