< Summary

Class:DCL.AssetPromise[AssetType]
Assembly:AssetPromiseKeeper
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/AssetManager/Common/AssetPromise.cs
Covered lines:69
Uncovered lines:5
Coverable lines:74
Total lines:196
Line coverage:93.2% (69 of 74)
Covered branches:0
Total branches:0
Covered methods:22
Total methods:22
Method coverage:100% (22 of 22)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ClearEvents()0%110100%
ForceFail(...)0%110100%
SetWaitingState()0%110100%
CallAndClearEvents(...)0%660100%
Load()0%5.055087.5%
GetLibraryAssetCheckId()0%110100%
GetAsset(...)0%110100%
OnReuse(...)0%220100%
OnReuseFinished()0%110100%
OnLoadSuccess()0%2.152066.67%
OnLoadFailure(...)0%2.032080%
AddToLibrary()0%110100%
Unload()0%220100%
Cleanup()0%440100%
OnForget()0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/AssetManager/Common/AssetPromise.cs

#LineLine coverage
 1using System;
 2using UnityEngine;
 3
 4namespace DCL
 5{
 6    public enum AssetPromiseState
 7    {
 8        IDLE_AND_EMPTY,
 9        WAITING,
 10        LOADING,
 11        FINISHED
 12    }
 13
 14    /// <summary>
 15    /// AssetPromise is in charge of handling all the logic related to loading the specified AssetType.
 16    /// It also should return the cached asset if applicable.
 17    ///
 18    /// If we need settings related to how the asset should be loaded/handled, we add them here.
 19    ///
 20    /// If we need many ways of loading the same Asset type, we can create different AssetPromise
 21    /// subclasses to do so. This can be useful to attach the GLTFSceneImporter loading logic for
 22    /// materials/textures to system.
 23    /// </summary>
 24    /// <typeparam name="AssetType">The Asset type to be loaded.</typeparam>
 25    public abstract class AssetPromise<AssetType> : CustomYieldInstruction
 26        where AssetType : Asset, new()
 27    {
 28        internal bool isDirty = false;
 29        internal AssetLibrary<AssetType> library;
 907130        public AssetType asset { get; protected set; }
 31
 4056432        public AssetPromiseState state { get; protected set; }
 73933        public bool isForgotten { get; protected set; }
 34
 35        internal event Action<AssetPromise<AssetType>> OnPreFinishEvent;
 36        public event Action<AssetType> OnSuccessEvent;
 37        public event Action<AssetType, Exception> OnFailEvent;
 38
 2889939        public override bool keepWaiting { get { return state == AssetPromiseState.LOADING || state == AssetPromiseState
 40
 41        public void ClearEvents()
 42        {
 128443            OnSuccessEvent = null;
 128444            OnFailEvent = null;
 128445        }
 46
 47        internal void ForceFail(Exception reason)
 48        {
 649            OnPreFinishEvent = null;
 650            CallAndClearEvents(false, reason);
 651            state = AssetPromiseState.IDLE_AND_EMPTY;
 652        }
 53
 54        internal void SetWaitingState()
 55        {
 56            //TODO(Brian): This is made to make the promises yielding not return automatically when the promise is block
 57            //
 58            //             Managing the blocked promises handling entirely in the AssetPromiseKeeper is coupling the cod
 59            //             It's better to have a "WaitForPromise" method here and lighten the APK logic a bit. For now t
 11360            state = AssetPromiseState.WAITING;
 11361        }
 62
 63        protected void CallAndClearEvents(bool isSuccess, Exception exception)
 64        {
 65765            if (asset == null)
 66            {
 2667                isSuccess = false;
 68            }
 69
 65770            OnPreFinishEvent?.Invoke(this);
 65771            OnPreFinishEvent = null;
 72
 65773            if (isSuccess)
 61374                OnSuccessEvent?.Invoke(asset);
 75            else
 4476                OnFailEvent?.Invoke(asset, exception);
 77
 65778            ClearEvents();
 65779        }
 80
 81        internal virtual void Load()
 82        {
 69883            if (state == AssetPromiseState.LOADING || state == AssetPromiseState.FINISHED)
 284                return;
 85
 69686            state = AssetPromiseState.LOADING;
 87
 88            // NOTE(Brian): Get existent library element
 69689            object libraryAssetCheckId = GetLibraryAssetCheckId();
 69690            if (library.Contains(libraryAssetCheckId))
 91            {
 16092                asset = GetAsset(libraryAssetCheckId);
 93
 16094                if (asset != null)
 95                {
 16096                    OnBeforeLoadOrReuse();
 16097                    OnReuse(OnReuseFinished);
 98                }
 99                else
 100                {
 0101                    CallAndClearEvents(false, new Exception("Asset is null"));
 102                }
 103
 0104                return;
 105            }
 106
 107            // NOTE(Brian): Get new library element
 536108            asset = new AssetType();
 536109            OnBeforeLoadOrReuse();
 536110            asset.id = GetId();
 111
 536112            OnLoad(OnLoadSuccess, OnLoadFailure);
 536113        }
 114
 555115        protected virtual object GetLibraryAssetCheckId() { return GetId(); }
 116
 151117        protected virtual AssetType GetAsset(object id) { return library.Get(id); }
 118
 256119        protected virtual void OnReuse(Action OnFinish) { OnFinish?.Invoke(); }
 120
 121        protected void OnReuseFinished()
 122        {
 160123            OnAfterLoadOrReuse();
 160124            state = AssetPromiseState.FINISHED;
 160125            CallAndClearEvents(true, null);
 160126        }
 127
 128        protected void OnLoadSuccess()
 129        {
 453130            if (AddToLibrary())
 131            {
 453132                OnAfterLoadOrReuse();
 453133                state = AssetPromiseState.FINISHED;
 453134                CallAndClearEvents(true, null);
 135            }
 136            else
 137            {
 0138                OnLoadFailure(new Exception("Could not add asset to library"));
 139            }
 0140        }
 141
 142        protected void OnLoadFailure(Exception exception)
 143        {
 144#if UNITY_STANDALONE || UNITY_EDITOR
 38145            if (DataStore.i.common.isApplicationQuitting.Get())
 0146                return;
 147#endif
 148
 38149            CallAndClearEvents(false, exception);
 38150            Cleanup();
 38151        }
 152
 10153        protected virtual bool AddToLibrary() { return library.Add(asset); }
 154
 155        internal virtual void Unload()
 156        {
 439157            if (state == AssetPromiseState.IDLE_AND_EMPTY)
 6158                return;
 159
 433160            Cleanup();
 433161        }
 162
 163        public virtual void Cleanup()
 164        {
 529165            if (state == AssetPromiseState.LOADING)
 166            {
 83167                OnCancelLoading();
 83168                ClearEvents();
 169            }
 170
 529171            state = AssetPromiseState.IDLE_AND_EMPTY;
 172
 529173            if (asset != null)
 174            {
 469175                if (library.Contains(asset))
 347176                    library.Release(asset);
 177                else
 122178                    asset.Cleanup();
 179
 469180                asset = null;
 181            }
 529182        }
 183
 184        internal virtual void OnForget()
 185        {
 544186            isForgotten = true;
 544187            ClearEvents();
 544188        }
 189
 190        protected abstract void OnCancelLoading();
 191        protected abstract void OnLoad(Action OnSuccess, Action<Exception> OnFail);
 192        protected abstract void OnBeforeLoadOrReuse();
 193        protected abstract void OnAfterLoadOrReuse();
 194        public abstract object GetId();
 195    }
 196}