< Summary

Class:AvatarSystem.WearableLoader
Assembly:AvatarSystem
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/AvatarSystem/Loader/WearableLoader.cs
Covered lines:49
Uncovered lines:7
Coverable lines:56
Total lines:125
Line coverage:87.5% (49 of 56)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
WearableLoader()0%110100%
WearableLoader(...)0%110100%
Load()0%12.2612087.88%
FallbackToDefault()0%9.546053.85%
LoadWearable()0%4.184077.78%
Dispose()0%220100%

File(s)

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

#LineLine coverage
 1using System;
 2using System.Threading;
 3using Cysharp.Threading.Tasks;
 4using DCL;
 5using UnityEngine;
 6
 7namespace AvatarSystem
 8{
 9    public class WearableLoader : IWearableLoader
 10    {
 11        // TODO: This should be a service
 112        internal static IWearableItemResolver defaultWearablesResolver = new WearableItemResolver();
 13        static WearableLoader()
 14        {
 15            // Prewarm default wearables
 116            defaultWearablesResolver.Resolve(WearableLiterals.DefaultWearables.GetDefaultWearables());
 117        }
 18
 119        public WearableItem wearable { get; }
 3620        public Rendereable rendereable => retriever?.rendereable;
 021        public IWearableLoader.Status status { get; private set; }
 22
 23        private readonly IWearableRetriever retriever;
 24        private AvatarSettings currentSettings;
 25
 1626        public WearableLoader(IWearableRetriever retriever, WearableItem wearable)
 27        {
 1628            this.wearable = wearable;
 1629            this.retriever = retriever;
 1630        }
 31
 32        public async UniTask Load(GameObject container, AvatarSettings settings, CancellationToken ct = default)
 33        {
 1534            ct.ThrowIfCancellationRequested();
 35
 36            try
 37            {
 1438                bool bodyshapeDirty = currentSettings.bodyshapeId != settings.bodyshapeId;
 1439                currentSettings = settings;
 1440                if (status == IWearableLoader.Status.Succeeded && !bodyshapeDirty)
 41                {
 042                    AvatarSystemUtils.PrepareMaterialColors(rendereable, currentSettings.skinColor, currentSettings.hair
 043                    return;
 44                }
 45
 1446                retriever.Dispose();
 47
 48                try
 49                {
 3050                    await LoadWearable(container, wearable, settings.bodyshapeId, ct);
 1151                }
 152                catch (OperationCanceledException)
 53                {
 154                    throw;
 55                }
 256                catch (Exception e)
 57                {
 58                    // Ignored so we try to fallback (if needed)
 259                }
 60
 61                // Succeeded
 1362                if (rendereable != null)
 63                {
 964                    AvatarSystemUtils.PrepareMaterialColors(rendereable, currentSettings.skinColor, currentSettings.hair
 965                    status = IWearableLoader.Status.Succeeded;
 966                    return;
 67                }
 68
 69                //Try getting a default if category is needed
 470                if (AvatarSystemUtils.IsCategoryRequired(wearable.data.category))
 271                    await FallbackToDefault(container, ct);
 72
 473                if (rendereable != null)
 74                {
 275                    AvatarSystemUtils.PrepareMaterialColors(rendereable, currentSettings.skinColor, currentSettings.hair
 276                    status = IWearableLoader.Status.Defaulted;
 277                }
 78                else
 279                    status = IWearableLoader.Status.Failed;
 480            }
 181            catch (OperationCanceledException)
 82            {
 183                Dispose();
 184                throw;
 85            }
 1386        }
 87
 88        private async UniTask FallbackToDefault(GameObject container, CancellationToken ct)
 89        {
 290            ct.ThrowIfCancellationRequested();
 91
 92            try
 93            {
 294                string wearableId = WearableLiterals.DefaultWearables.GetDefaultWearable(currentSettings.bodyshapeId, we
 295                Debug.Log($"Falling back {wearable.id} to wearable {wearableId}");
 96
 297                WearableItem defaultWearable = await defaultWearablesResolver.Resolve(wearableId, ct);
 98
 299                await LoadWearable(container, defaultWearable, currentSettings.bodyshapeId, ct);
 2100            }
 0101            catch (OperationCanceledException)
 102            {
 103                //No disposing required
 0104                throw;
 105            }
 106
 2107        }
 108
 109        private async UniTask LoadWearable(GameObject container, WearableItem wearableToLoad, string bodyshapeId, Cancel
 110        {
 16111            ct.ThrowIfCancellationRequested();
 112
 16113            WearableItem.Representation representation = wearableToLoad.GetRepresentation(bodyshapeId);
 16114            if (representation == null)
 115            {
 0116                Debug.Log($"No representation for {bodyshapeId} of {wearableToLoad.id}");
 0117                return;
 118            }
 119
 32120            await retriever.Retrieve(container, wearableToLoad.GetContentProvider(bodyshapeId), wearableToLoad.baseUrlBu
 13121        }
 122
 16123        public void Dispose() { retriever?.Dispose(); }
 124    }
 125}