< Summary

Class:AvatarSystem.WearableLoader
Assembly:AvatarSystemLoaders
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/AvatarSystem/Loader/WearableLoader.cs
Covered lines:25
Uncovered lines:27
Coverable lines:52
Total lines:122
Line coverage:48% (25 of 52)
Covered branches:0
Total branches:0
Covered methods:8
Total methods:11
Method coverage:72.7% (8 of 11)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
WearableLoader()0%110100%
WearableLoader(...)0%110100%
Load()0%37.6312043.75%
SetBones(...)0%2100%
FallbackToDefault()0%42600%
LoadWearable()0%330100%
Dispose()0%6200%

File(s)

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

#LineLine coverage
 1using System.Linq;
 2using System.Threading;
 3using Cysharp.Threading.Tasks;
 4using DCL;
 5using DCLServices.WearablesCatalogService;
 6using System;
 7using UnityEngine;
 8using Environment = DCL.Environment;
 9
 10namespace AvatarSystem
 11{
 12    public class WearableLoader : IWearableLoader
 13    {
 14        // TODO: This should be a service
 115        internal static IWearableItemResolver defaultWearablesResolver = new WearableItemResolver(Environment.i.serviceL
 16        static WearableLoader()
 17        {
 18            // Prewarm default wearables
 119            defaultWearablesResolver.Resolve(WearableLiterals.DefaultWearables.GetDefaultWearables());
 120        }
 21
 222        public WearableItem bodyShape { get; }
 623        public Rendereable rendereable => retriever?.rendereable;
 6424        public IWearableLoader.Status status { get; private set; }
 25
 26        private readonly IWearableRetriever retriever;
 27        private AvatarSettings currentSettings;
 28
 229        public WearableLoader(IWearableRetriever retriever, WearableItem wearable)
 30        {
 231            this.bodyShape = wearable;
 232            this.retriever = retriever;
 233        }
 34
 35        public async UniTask Load(GameObject container, AvatarSettings settings, CancellationToken ct = default)
 36        {
 237            ct.ThrowIfCancellationRequested();
 38
 39            try
 40            {
 241                bool bodyshapeDirty = currentSettings.bodyshapeId != settings.bodyshapeId;
 242                currentSettings = settings;
 243                if (status == IWearableLoader.Status.Succeeded && !bodyshapeDirty)
 44                {
 045                    AvatarSystemUtils.PrepareMaterialColors(rendereable, currentSettings.skinColor, currentSettings.hair
 046                    return;
 47                }
 48
 249                retriever.Dispose();
 50
 51                try
 52                {
 653                    await LoadWearable(container, bodyShape, settings.bodyshapeId, ct);
 254                }
 055                catch (OperationCanceledException)
 56                {
 057                    throw;
 58                }
 059                catch (Exception e)
 60                {
 61                    // Ignored so we try to fallback (if needed)
 062                }
 63
 64                // Succeeded
 265                if (rendereable != null)
 66                {
 267                    AvatarSystemUtils.PrepareMaterialColors(rendereable, currentSettings.skinColor, currentSettings.hair
 268                    status = IWearableLoader.Status.Succeeded;
 269                    return;
 70                }
 71
 72                //Try getting a default if category is needed
 073                if (AvatarSystemUtils.IsCategoryRequired(bodyShape.data.category))
 074                    await FallbackToDefault(container, ct);
 75
 076                if (rendereable != null)
 77                {
 078                    AvatarSystemUtils.PrepareMaterialColors(rendereable, currentSettings.skinColor, currentSettings.hair
 079                    status = IWearableLoader.Status.Defaulted;
 80                }
 81                else
 082                    status = IWearableLoader.Status.Failed;
 083            }
 084            catch (OperationCanceledException)
 85            {
 086                Dispose();
 087                throw;
 88            }
 289        }
 90
 091        public void SetBones(Transform rootBone, Transform[] bones) { AvatarSystemUtils.CopyBones(rootBone, bones, rende
 92
 93        private async UniTask FallbackToDefault(GameObject container, CancellationToken ct)
 94        {
 095            ct.ThrowIfCancellationRequested();
 96
 97            try
 98            {
 099                string wearableId = WearableLiterals.DefaultWearables.GetDefaultWearable(currentSettings.bodyshapeId, bo
 0100                Debug.Log($"Falling back {bodyShape.id} to wearable {wearableId}");
 101
 0102                WearableItem defaultWearable = await defaultWearablesResolver.Resolve(wearableId, ct);
 103
 0104                await LoadWearable(container, defaultWearable, currentSettings.bodyshapeId, ct);
 0105            }
 0106            catch (OperationCanceledException)
 107            {
 108                //No disposing required
 0109                throw;
 110            }
 111
 0112        }
 113
 114        private async UniTask LoadWearable(GameObject container, WearableItem wearableToLoad, string bodyshapeId, Cancel
 115        {
 2116            ct.ThrowIfCancellationRequested();
 6117            await retriever.Retrieve(container, wearableToLoad, bodyshapeId, ct);
 2118        }
 119
 0120        public void Dispose() { retriever?.Dispose(); }
 121    }
 122}