< Summary

Class:AvatarSystem.WearableItemResolver
Assembly:AvatarSystem
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/AvatarSystem/WearableItemResolver.cs
Covered lines:19
Uncovered lines:28
Coverable lines:47
Total lines:121
Line coverage:40.4% (19 of 47)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
WearableItemResolver()0%110100%
ResolveAndSplit()0%42600%
Resolve()0%6.984042.86%
Resolve()0%71.6915036.84%
Forget(...)0%2.152066.67%
Forget(...)0%2100%
Dispose()0%330100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/AvatarSystem/WearableItemResolver.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Threading;
 5using Cysharp.Threading.Tasks;
 6using DCL.Helpers;
 7
 8namespace AvatarSystem
 9{
 10    public class WearableItemResolver : IWearableItemResolver
 11    {
 66312        private CancellationTokenSource disposeCts = new CancellationTokenSource();
 66313        private readonly Dictionary<string, WearableItem> wearablesRetrieved = new Dictionary<string, WearableItem>();
 14
 15        public async UniTask<(List<WearableItem> wearables, List<WearableItem> emotes)> ResolveAndSplit(IEnumerable<stri
 16        {
 17            try
 18            {
 019                WearableItem[] allItems = await Resolve(wearableIds, ct);
 20
 021                List<WearableItem> wearables = new List<WearableItem>();
 022                List<WearableItem> emotes = new List<WearableItem>();
 23
 024                for (int i = 0; i < allItems.Length; i++)
 25                {
 026                    if (allItems[i] == null)
 27                        continue;
 28
 029                    if (allItems[i].IsEmote())
 030                        emotes.Add(allItems[i]);
 31                    else
 032                        wearables.Add(allItems[i]);
 33                }
 34
 035                return (
 36                    wearables,
 37                    emotes
 38                );
 39            }
 040            catch (OperationCanceledException)
 41            {
 42                //No disposing required
 043                throw;
 44            }
 045        }
 46
 47        public async UniTask<WearableItem[]> Resolve(IEnumerable<string> wearableId, CancellationToken ct = default)
 48        {
 149            ct.ThrowIfCancellationRequested();
 50
 51            try
 52            {
 53
 1754                return await UniTask.WhenAll(wearableId.Select(x => Resolve(x, ct)));
 55            }
 056            catch (OperationCanceledException)
 57            {
 58                //No disposing required
 059                throw;
 60            }
 061        }
 62
 63        public async UniTask<WearableItem> Resolve(string wearableId, CancellationToken ct = default)
 64        {
 1565            if (disposeCts == null)
 066                disposeCts = new CancellationTokenSource();
 1567            using CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(ct, disposeCts.Tok
 68
 1569            linkedCts.Token.ThrowIfCancellationRequested();
 70
 71            try
 72            {
 1573                if (wearablesRetrieved.ContainsKey(wearableId))
 074                    return wearablesRetrieved[wearableId];
 75
 1576                Promise<WearableItem> promise = CatalogController.RequestWearable(wearableId);
 77                // AttachExternalCancellation is needed because a CustomYieldInstruction requires a frame to operate
 3078                await promise.WithCancellation(linkedCts.Token);
 79
 80                // Cancelling is irrelevant at this point,
 81                // either we have the wearable and we have to add it to forget it later
 82                // or it's null and we just return it
 083                if (promise.value != null)
 084                    wearablesRetrieved.Add(wearableId, promise.value);
 85
 086                return promise.value;
 87
 88            }
 089            catch (Exception ex) when (ex is OperationCanceledException or PromiseException)
 90            {
 091                wearablesRetrieved.Remove(wearableId);
 092                return null;
 93            }
 94            finally
 95            {
 096                disposeCts?.Dispose();
 097                disposeCts = null;
 98            }
 099        }
 100
 101        public void Forget(List<string> wearableIds)
 102        {
 1336103            foreach (string wearableId in wearableIds)
 104            {
 0105                wearablesRetrieved.Remove(wearableId);
 106            }
 668107            CatalogController.RemoveWearablesInUse(wearableIds);
 668108        }
 109
 0110        public void Forget(string wearableId) { CatalogController.RemoveWearablesInUse(new List<string> { wearableId });
 111
 112        public void Dispose()
 113        {
 668114            disposeCts?.Cancel();
 668115            disposeCts?.Dispose();
 668116            disposeCts = null;
 668117            Forget(wearablesRetrieved.Keys.ToList());
 668118            wearablesRetrieved.Clear();
 668119        }
 120    }
 121}