< 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:61
Uncovered lines:12
Coverable lines:73
Total lines:190
Line coverage:83.5% (61 of 73)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ClearEvents()0%2100%
ForceFail()0%110100%
SetWaitingState()0%2100%
CallAndClearEvents(...)0%660100%
Load()0%5.045088.24%
GetLibraryAssetCheckId()0%110100%
GetAsset(...)0%110100%
OnReuse(...)0%220100%
OnReuseFinished()0%110100%
OnLoadSuccess()0%2.092071.43%
OnLoadFailure()0%110100%
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;
 030        public AssetType asset { get; protected set; }
 31
 032        public AssetPromiseState state { get; protected set; }
 033        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> OnFailEvent;
 38
 487739        public override bool keepWaiting { get { return state == AssetPromiseState.LOADING || state == AssetPromiseState
 40
 41        public void ClearEvents()
 42        {
 043            OnSuccessEvent = null;
 044            OnFailEvent = null;
 045        }
 46
 47        internal void ForceFail()
 48        {
 849            OnPreFinishEvent = null;
 850            CallAndClearEvents(false);
 851            state = AssetPromiseState.IDLE_AND_EMPTY;
 852        }
 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
 060            state = AssetPromiseState.WAITING;
 061        }
 62
 63        protected void CallAndClearEvents(bool isSuccess = true)
 64        {
 32065            if (asset == null)
 66            {
 2867                isSuccess = false;
 68            }
 69
 32070            OnPreFinishEvent?.Invoke(this);
 32071            OnPreFinishEvent = null;
 72
 32073            Action<AssetType> finalEvent = isSuccess ? OnSuccessEvent : OnFailEvent;
 74
 32075            finalEvent?.Invoke(asset);
 76
 32077            ClearEvents();
 32078        }
 79
 80        internal virtual void Load()
 81        {
 34682            if (state == AssetPromiseState.LOADING || state == AssetPromiseState.FINISHED)
 283                return;
 84
 34485            state = AssetPromiseState.LOADING;
 86
 87            // NOTE(Brian): Get existent library element
 34488            object libraryAssetCheckId = GetLibraryAssetCheckId();
 34489            if (library.Contains(libraryAssetCheckId))
 90            {
 12591                asset = GetAsset(libraryAssetCheckId);
 92
 12593                if (asset != null)
 94                {
 12595                    OnBeforeLoadOrReuse();
 12596                    OnReuse(OnReuseFinished);
 12597                }
 98                else
 99                {
 0100                    CallAndClearEvents(false);
 101                }
 102
 0103                return;
 104            }
 105
 106            // NOTE(Brian): Get new library element
 219107            asset = new AssetType();
 219108            OnBeforeLoadOrReuse();
 219109            asset.id = GetId();
 110
 219111            OnLoad(OnLoadSuccess, OnLoadFailure);
 219112        }
 113
 273114        protected virtual object GetLibraryAssetCheckId() { return GetId(); }
 115
 107116        protected virtual AssetType GetAsset(object id) { return library.Get(id); }
 117
 148118        protected virtual void OnReuse(Action OnFinish) { OnFinish?.Invoke(); }
 119
 120        protected void OnReuseFinished()
 121        {
 123122            OnAfterLoadOrReuse();
 123123            state = AssetPromiseState.FINISHED;
 123124            CallAndClearEvents(isSuccess: true);
 123125        }
 126
 127        protected void OnLoadSuccess()
 128        {
 134129            if (AddToLibrary())
 130            {
 134131                OnAfterLoadOrReuse();
 134132                state = AssetPromiseState.FINISHED;
 134133                CallAndClearEvents(isSuccess: true);
 134134            }
 135            else
 136            {
 0137                OnLoadFailure();
 138            }
 0139        }
 140
 141        protected void OnLoadFailure()
 142        {
 55143            CallAndClearEvents(isSuccess: false);
 55144            Cleanup();
 55145        }
 146
 7147        protected virtual bool AddToLibrary() { return library.Add(asset); }
 148
 149        internal void Unload()
 150        {
 193151            if (state == AssetPromiseState.IDLE_AND_EMPTY)
 6152                return;
 153
 187154            Cleanup();
 187155        }
 156
 157        public void Cleanup()
 158        {
 251159            if (state == AssetPromiseState.LOADING)
 160            {
 85161                OnCancelLoading();
 85162                ClearEvents();
 163            }
 164
 251165            state = AssetPromiseState.IDLE_AND_EMPTY;
 166
 251167            if (asset != null)
 168            {
 226169                if (library.Contains(asset))
 143170                    library.Release(asset);
 171                else
 83172                    asset.Cleanup();
 173
 226174                asset = null;
 175            }
 251176        }
 177
 178        internal virtual void OnForget()
 179        {
 486180            isForgotten = true;
 486181            ClearEvents();
 486182        }
 183
 184        protected abstract void OnCancelLoading();
 185        protected abstract void OnLoad(Action OnSuccess, Action OnFail);
 186        protected abstract void OnBeforeLoadOrReuse();
 187        protected abstract void OnAfterLoadOrReuse();
 188        public abstract object GetId();
 189    }
 190}