< Summary

Class:FacialFeatureController
Assembly:AvatarShape
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Avatar/FacialFeatureController.cs
Covered lines:41
Uncovered lines:27
Coverable lines:68
Total lines:144
Line coverage:60.2% (41 of 68)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
FacialFeatureController(...)0%110100%
Load(...)0%2.092071.43%
PrepareWearable()0%6.296080%
FetchTextures()0%29.4329092%
CleanUp()0%20400%
CreateDefaultFacialFeature(...)0%6200%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Avatar/FacialFeatureController.cs

#LineLine coverage
 1using DCL.Helpers;
 2using System.Collections;
 3using System.Linq;
 4using UnityEngine;
 5using DCL;
 6
 7public class FacialFeatureController : CustomYieldInstruction
 8{
 09    public bool isReady { get; private set; }
 010    public string wearableId => wearableItem?.id;
 11
 12    private readonly WearableItem wearableItem;
 13    private readonly Material baseMaterial;
 14
 15    internal Texture mainTexture = null;
 16    internal Texture maskTexture = null;
 17    internal AssetPromise_Texture mainTexturePromise = null;
 18    internal AssetPromise_Texture maskTexturePromise = null;
 19
 20    private Color color;
 21    private IBodyShapeController bodyShape;
 22    internal Material baseMaterialCopy;
 23    private Coroutine fetchTextureCoroutine;
 24
 425    public FacialFeatureController(WearableItem wearableItem, Material baseMaterial)
 26    {
 427        isReady = false;
 428        this.baseMaterial = baseMaterial;
 429        this.wearableItem = wearableItem;
 430    }
 31
 32    public void Load(IBodyShapeController loadedBody, Color color)
 33    {
 434        this.color = color;
 35
 436        if (isReady)
 37        {
 038            PrepareWearable();
 039            return;
 40        }
 41
 442        this.bodyShape = loadedBody;
 443        fetchTextureCoroutine = CoroutineStarter.Start(FetchTextures());
 444    }
 45
 46    void PrepareWearable()
 47    {
 448        if (baseMaterialCopy == null)
 449            baseMaterialCopy = new Material(baseMaterial);
 50
 451        switch (wearableItem.data.category)
 52        {
 53            case WearableLiterals.Categories.EYES:
 354                bodyShape.SetupEyes(baseMaterialCopy, mainTexture, maskTexture, color);
 355                break;
 56            case WearableLiterals.Categories.EYEBROWS:
 057                bodyShape.SetupEyebrows(baseMaterialCopy, mainTexture, color);
 058                break;
 59            case WearableLiterals.Categories.MOUTH:
 160                bodyShape.SetupMouth(baseMaterialCopy, mainTexture, maskTexture, color);
 61                break;
 62        }
 63
 464        isReady = true;
 465    }
 66
 67    private IEnumerator FetchTextures()
 68    {
 469        if (mainTexturePromise != null)
 070            AssetPromiseKeeper_Texture.i.Forget(mainTexturePromise);
 71
 472        if (maskTexturePromise != null)
 073            AssetPromiseKeeper_Texture.i.Forget(maskTexturePromise);
 74
 475        mainTexture = null;
 476        maskTexture = null;
 77
 478        var representation = wearableItem.GetRepresentation(bodyShape.bodyShapeId);
 79
 880        string mainTextureHash = representation?.contents?.FirstOrDefault(x => x.key == representation?.mainFile)?.hash;
 481        if (mainTextureHash == null)
 382            mainTextureHash = representation?.contents?.FirstOrDefault(x => !x.key.ToLower().Contains("_mask.png"))?.has
 1083        string maskhash = representation?.contents?.FirstOrDefault(x => x.key.ToLower().Contains("_mask.png"))?.hash;
 84
 485        if (!string.IsNullOrEmpty(mainTextureHash))
 86        {
 387            mainTexturePromise = new AssetPromise_Texture(wearableItem.baseUrl + mainTextureHash);
 588            mainTexturePromise.OnSuccessEvent += (x) => mainTexture = x.texture;
 489            mainTexturePromise.OnFailEvent += (x) => mainTexture = null;
 90
 391            AssetPromiseKeeper_Texture.i.Keep(mainTexturePromise);
 92        }
 93
 494        if (!string.IsNullOrEmpty(maskhash))
 95        {
 396            maskTexturePromise = new AssetPromise_Texture(wearableItem.baseUrl + maskhash);
 597            maskTexturePromise.OnSuccessEvent += (x) => maskTexture = x.texture;
 498            maskTexturePromise.OnFailEvent += (x) => maskTexture = null;
 99
 3100            AssetPromiseKeeper_Texture.i.Keep(maskTexturePromise);
 101        }
 102
 4103        yield return mainTexturePromise;
 4104        yield return maskTexturePromise;
 105
 4106        PrepareWearable();
 4107    }
 108
 109    public void CleanUp()
 110    {
 0111        if (mainTexturePromise != null)
 0112            AssetPromiseKeeper_Texture.i.Forget(mainTexturePromise);
 113
 0114        if (maskTexturePromise != null)
 0115            AssetPromiseKeeper_Texture.i.Forget(maskTexturePromise);
 116
 0117        if ( baseMaterialCopy != null )
 118        {
 0119            Object.Destroy(baseMaterialCopy);
 0120            baseMaterialCopy = null;
 121        }
 122
 0123        CoroutineStarter.Stop(fetchTextureCoroutine);
 124
 0125        mainTexture = null;
 0126        maskTexture = null;
 0127        isReady = false;
 0128    }
 129
 130    public static FacialFeatureController CreateDefaultFacialFeature(string bodyShape, string category, Material materia
 131    {
 0132        string defaultId = WearableLiterals.DefaultWearables.GetDefaultWearable(bodyShape, category);
 0133        CatalogController.wearableCatalog.TryGetValue(defaultId, out WearableItem wearable);
 0134        if (wearable == null)
 135        {
 0136            Debug.LogError($"Couldn't resolve wearable {defaultId}");
 0137            return null;
 138        }
 139
 0140        return new FacialFeatureController(wearable, material);
 141    }
 142
 0143    public override bool keepWaiting => !isReady;
 144}