< Summary

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

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
WearableItemResolver()0%110100%
ResolveAndSplit()0%6.016093.75%
Resolve()0%440100%
Resolve()0%12.0212094.44%
Forget(...)0%220100%
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    {
 130612        private CancellationTokenSource disposeCts = new CancellationTokenSource();
 130613        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            {
 7919                WearableItem[] allItems = await Resolve(wearableIds, ct);
 20
 7621                List<WearableItem> wearables = new List<WearableItem>();
 7622                List<WearableItem> emotes = new List<WearableItem>();
 23
 127624                for (int i = 0; i < allItems.Length; i++)
 25                {
 56226                    if (allItems[i] == null)
 27                        continue;
 28
 56229                    if (allItems[i].IsEmote())
 030                        emotes.Add(allItems[i]);
 31                    else
 56232                        wearables.Add(allItems[i]);
 33                }
 34
 7635                return (
 36                    wearables,
 37                    emotes
 38                );
 39            }
 140            catch (OperationCanceledException)
 41            {
 42                //No disposing required
 143                throw;
 44            }
 7645        }
 46
 47        public async UniTask<WearableItem[]> Resolve(IEnumerable<string> wearableId, CancellationToken ct = default)
 48        {
 7849            ct.ThrowIfCancellationRequested();
 50
 51            try
 52            {
 53
 69054                return await UniTask.WhenAll(wearableId.Select(x => Resolve(x, ct)));
 55            }
 156            catch (OperationCanceledException)
 57            {
 58                //No disposing required
 159                throw;
 60            }
 7661        }
 62
 63        public async UniTask<WearableItem> Resolve(string wearableId, CancellationToken ct = default)
 64        {
 60965            if (disposeCts == null)
 52666                disposeCts = new CancellationTokenSource();
 60967            using CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(ct, disposeCts.Tok
 68
 60969            linkedCts.Token.ThrowIfCancellationRequested();
 70
 71            try
 72            {
 60973                if (wearablesRetrieved.ContainsKey(wearableId))
 074                    return wearablesRetrieved[wearableId];
 75
 60976                Promise<WearableItem> promise = CatalogController.RequestWearable(wearableId);
 77                // AttachExternalCancellation is needed because a CustomYieldInstruction requires a frame to operate
 67078                await promise.WithCancellation(linkedCts.Token).AttachExternalCancellation(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
 57183                if (promise.value != null)
 57184                    wearablesRetrieved.Add(wearableId, promise.value);
 85
 57186                return promise.value;
 87
 88            }
 2389            catch (OperationCanceledException)
 90            {
 91                //No disposing required
 2392                throw;
 93            }
 94            finally
 95            {
 59496                disposeCts?.Dispose();
 59497                disposeCts = null;
 98            }
 57199        }
 100
 101        public void Forget(List<string> wearableIds)
 102        {
 3954103            foreach (string wearableId in wearableIds)
 104            {
 571105                wearablesRetrieved.Remove(wearableId);
 106            }
 1406107            CatalogController.RemoveWearablesInUse(wearableIds);
 1406108        }
 109
 0110        public void Forget(string wearableId) { CatalogController.RemoveWearablesInUse(new List<string> { wearableId });
 111
 112        public void Dispose()
 113        {
 1406114            disposeCts?.Cancel();
 1406115            disposeCts?.Dispose();
 1406116            disposeCts = null;
 1406117            Forget(wearablesRetrieved.Keys.ToList());
 1406118            wearablesRetrieved.Clear();
 1406119        }
 120    }
 121}