< 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:29
Coverable lines:48
Total lines:123
Line coverage:39.5% (19 of 48)
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%51.5512035%
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    {
 103612        private CancellationTokenSource disposeCts = new CancellationTokenSource();
 103613        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).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
 083                if (promise.value != null)
 084                    wearablesRetrieved.Add(wearableId, promise.value);
 85
 086                return promise.value;
 87
 88            }
 089            catch (OperationCanceledException ex)
 90            {
 091                wearablesRetrieved.Remove(wearableId);
 92
 093                UnityEngine.Debug.LogError($"Resolve wearable OperationCanceledException: {ex.Message} {ex.StackTrace}")
 094                return null;
 95            }
 96            finally
 97            {
 098                disposeCts?.Dispose();
 099                disposeCts = null;
 100            }
 0101        }
 102
 103        public void Forget(List<string> wearableIds)
 104        {
 2094105            foreach (string wearableId in wearableIds)
 106            {
 0107                wearablesRetrieved.Remove(wearableId);
 108            }
 1047109            CatalogController.RemoveWearablesInUse(wearableIds);
 1047110        }
 111
 0112        public void Forget(string wearableId) { CatalogController.RemoveWearablesInUse(new List<string> { wearableId });
 113
 114        public void Dispose()
 115        {
 1047116            disposeCts?.Cancel();
 1047117            disposeCts?.Dispose();
 1047118            disposeCts = null;
 1047119            Forget(wearablesRetrieved.Keys.ToList());
 1047120            wearablesRetrieved.Clear();
 1047121        }
 122    }
 123}