< Summary

Class:DCL.Emotes.EmotesService
Assembly:EmotesService
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLServices/EmotesService/EmotesService.cs
Covered lines:30
Uncovered lines:31
Coverable lines:61
Total lines:162
Line coverage:49.1% (30 of 61)
Covered branches:0
Total branches:0
Covered methods:6
Total methods:8
Method coverage:75% (6 of 8)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
EmotesService(...)0%110100%
Initialize()0%110100%
InitializeAsync()0%880100%
SetupEmbeddedExtendedEmote(...)0%110100%
SetupEmbeddedClip(...)0%330100%
RequestEmote()0%3421800%
FetchEmote(...)0%30500%
Dispose()0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLServices/EmotesService/EmotesService.cs

#LineLine coverage
 1using AvatarAssets;
 2using Cysharp.Threading.Tasks;
 3using DCL.Configuration;
 4using DCLServices.EmotesService;
 5using DCLServices.WearablesCatalogService;
 6using System;
 7using System.Collections.Generic;
 8using System.Threading;
 9using UnityEngine;
 10using Object = UnityEngine.Object;
 11
 12namespace DCL.Emotes
 13{
 14    public class EmotesService : IEmotesService
 15    {
 16        //To avoid circular references in assemblies we hardcode this here instead of using WearableLiterals
 17        //Embedded Emotes are only temporary until they can be retrieved from the content server
 18        private const string FEMALE = "urn:decentraland:off-chain:base-avatars:BaseFemale";
 19        private const string MALE = "urn:decentraland:off-chain:base-avatars:BaseMale";
 20
 21        private readonly EmoteAnimationLoaderFactory emoteAnimationLoaderFactory;
 22        private readonly IEmotesCatalogService emotesCatalogService;
 23        private readonly IWearablesCatalogService wearablesCatalogService;
 24        private readonly ICatalyst catalyst;
 25        private GameObject animationsModelsContainer;
 26        private readonly EmoteVolumeHandler audioVolumeHandler;
 27
 42528        private readonly Dictionary<EmoteBodyId, IEmoteReference> embeddedEmotes = new ();
 42529        private readonly Dictionary<EmoteBodyId, ExtendedEmote> extendedEmotes = new ();
 30
 42531        public EmotesService(
 32            EmoteAnimationLoaderFactory emoteAnimationLoaderFactory,
 33            IEmotesCatalogService emotesCatalogService,
 34            IWearablesCatalogService wearablesCatalogService,
 35            ICatalyst catalyst)
 36        {
 42537            this.emoteAnimationLoaderFactory = emoteAnimationLoaderFactory;
 42538            this.emotesCatalogService = emotesCatalogService;
 42539            this.wearablesCatalogService = wearablesCatalogService;
 42540            this.catalyst = catalyst;
 42541        }
 42
 43        public void Initialize()
 44        {
 42545            animationsModelsContainer = new GameObject("_EmotesAnimationContainer")
 46            {
 47                transform =
 48                {
 49                    position = EnvironmentSettings.MORDOR,
 50                },
 51            };
 42552        }
 53
 54        public async UniTask InitializeAsync(CancellationToken cancellationToken)
 55        {
 47656            EmbeddedEmotesSO embedEmotes = await emotesCatalogService.GetEmbeddedEmotes();
 57
 58            // early return for not configured emotesCatalogService substitutes in legacy test base
 47159            if (embedEmotes == null) return;
 60
 136861            foreach (EmbeddedEmote embeddedEmote in embedEmotes.GetEmbeddedEmotes())
 62            {
 36363                if (embeddedEmote.maleAnimation != null)
 36364                    SetupEmbeddedClip(embeddedEmote, embeddedEmote.maleAnimation, MALE);
 65
 36366                if (embeddedEmote.femaleAnimation != null)
 36367                    SetupEmbeddedClip(embeddedEmote, embeddedEmote.femaleAnimation, FEMALE);
 68            }
 69
 66470            foreach (ExtendedEmote embeddedEmote in embedEmotes.GetExtendedEmbeddedEmotes())
 71            {
 1172                SetupEmbeddedExtendedEmote(embeddedEmote);
 73            }
 74
 32175            wearablesCatalogService.AddEmbeddedWearablesToCatalog(embedEmotes.GetAllEmotes());
 39676        }
 77
 78        private void SetupEmbeddedExtendedEmote(ExtendedEmote embeddedEmote)
 79        {
 1180            extendedEmotes.Add(new EmoteBodyId(MALE, embeddedEmote.id), embeddedEmote);
 1181            extendedEmotes.Add(new EmoteBodyId(FEMALE, embeddedEmote.id), embeddedEmote);
 1182        }
 83
 84        private void SetupEmbeddedClip(EmbeddedEmote embeddedEmote, AnimationClip clip, string urnPrefix)
 85        {
 72686            clip.name = embeddedEmote.id;
 72687            var clipData = new EmoteClipData(clip, embeddedEmote.emoteDataV0?.loop ?? false);
 72688            embeddedEmotes.Add(new EmoteBodyId(urnPrefix, embeddedEmote.id), new EmbedEmoteReference(embeddedEmote, clip
 72689        }
 90
 91        public async UniTask<IEmoteReference> RequestEmote(EmoteBodyId emoteBodyId, CancellationToken cancellationToken 
 92        {
 093            if (embeddedEmotes.TryGetValue(emoteBodyId, out var value))
 094                return value;
 95
 096            if (extendedEmotes.TryGetValue(emoteBodyId, out var extendedEmote))
 97            {
 098                IEmoteAnimationLoader loader = emoteAnimationLoaderFactory.Get();
 099                await loader.LoadLocalEmote(animationsModelsContainer, extendedEmote, cancellationToken);
 0100                return new NftEmoteReference(extendedEmote, loader, extendedEmote.emoteDataV0?.loop ?? false);
 101            }
 102
 103            try
 104            {
 0105                var emote = await FetchEmote(emoteBodyId, cancellationToken, contentUrl);
 106
 0107                if (emote == null)
 108                {
 0109                    Debug.LogError($"Unexpected null emote when requesting {emoteBodyId}");
 0110                    return null;
 111                }
 112
 113                // Loader disposal is being handled by the emote reference
 0114                IEmoteAnimationLoader animationLoader = emoteAnimationLoaderFactory.Get();
 0115                await animationLoader.LoadRemoteEmote(animationsModelsContainer, emote, emoteBodyId.BodyShapeId, cancell
 116
 0117                if (animationLoader.mainClip == null)
 0118                    Debug.LogError("Emote animation failed to load for emote " + emote.id);
 119
 0120                bool loop = emote is EmoteItem newEmoteItem ? newEmoteItem.data.loop : emote.emoteDataV0?.loop ?? false;
 0121                IEmoteReference emoteReference = new NftEmoteReference(emote, animationLoader, loop);
 0122                return emoteReference;
 123            }
 124            catch (Exception e)
 125            {
 0126                Debug.LogException(e);
 0127                return null;
 128            }
 0129        }
 130
 131        private UniTask<WearableItem> FetchEmote(EmoteBodyId emoteBodyId, CancellationToken ct, string contentUrl = null
 132        {
 0133            string emoteId = emoteBodyId.EmoteId;
 134
 0135            if (!SceneEmoteHelper.IsSceneEmote(emoteId))
 136            {
 0137                return emotesCatalogService.RequestEmoteAsync(emoteId, ct);
 138            }
 139
 0140            if (!emoteId.StartsWith("urn"))
 141            {
 0142                return emotesCatalogService.RequestEmoteFromBuilderAsync(emoteId, ct);
 143            }
 144
 0145            WearableItem emoteItem = null;
 0146            if (SceneEmoteHelper.TryGetDataFromEmoteId(emoteId, out string emoteHash, out bool loop))
 147            {
 0148                if (contentUrl != null)
 0149                    emoteItem = new EmoteItem(emoteBodyId.BodyShapeId, emoteId, emoteHash, contentUrl, loop, false);
 150                else
 0151                    emoteItem = new EmoteItem(emoteBodyId.BodyShapeId, emoteId, emoteHash, catalyst.contentUrl, loop);
 152            }
 153
 0154            return new UniTask<WearableItem>(emoteItem);
 155        }
 156
 157        public void Dispose()
 158        {
 425159            Object.Destroy(animationsModelsContainer);
 425160        }
 161    }
 162}