< Summary

Class:DCL.ECSComponents.ECSAudioSourceComponentHandler
Assembly:DCL.ECSComponents.AudioSource
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/AudioSource/Handler/ECSAudioSourceComponentHandler.cs
Covered lines:81
Uncovered lines:22
Coverable lines:103
Total lines:224
Line coverage:78.6% (81 of 103)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ECSAudioSourceComponentHandler(...)0%110100%
OnComponentCreated(...)0%220100%
OnComponentRemoved(...)0%110100%
OnComponentModelUpdated(...)0%9.498071.43%
UpdateOutOfBoundariesState(...)0%6200%
DisposePromise()0%2.022083.33%
Dispose(...)0%4.014091.67%
ApplyCurrentModel()0%5.255078.57%
ApplyLoadedAudioClip(...)0%550100%
OnAudioClipLoadComplete(...)0%2.022083.33%
OnAudioClipLoadFail(...)0%2100%
OnAudioSettingsChanged(...)0%2100%
OnVirtualAudioMixerChangedValue(...)0%2100%
UpdateAudioSourceVolume()0%770100%
OnCurrentSceneChanged(...)0%550100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/AudioSource/Handler/ECSAudioSourceComponentHandler.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using DCL.Controllers;
 5using DCL.ECSRuntime;
 6using DCL.Helpers;
 7using DCL.Models;
 8using DCL.SettingsCommon;
 9using UnityEngine;
 10using AudioSettings = DCL.SettingsCommon.AudioSettings;
 11
 12namespace DCL.ECSComponents
 13{
 14    public class ECSAudioSourceComponentHandler : IECSComponentHandler<PBAudioSource>, IOutOfSceneBoundariesHandler
 15    {
 16        internal AudioSource audioSource;
 17        internal AssetPromise_AudioClip promiseAudioClip;
 18
 19        private bool isOutOfBoundaries = false;
 20        private bool isAudioClipReady = false;
 21
 22        private PBAudioSource model;
 23        private IParcelScene scene;
 24        private AudioClip audioClip;
 25
 26        private DataStore dataStore;
 27        private Settings settings;
 28        private AssetPromiseKeeper_AudioClip keeperAudioClip;
 29        private IntVariable sceneNumber;
 30
 1031        public ECSAudioSourceComponentHandler(DataStore dataStoreInstance, Settings settingsInstance, AssetPromiseKeeper
 32        {
 1033            dataStore = dataStoreInstance;
 1034            settings = settingsInstance;
 1035            keeperAudioClip = keeperInstance;
 1036            this.sceneNumber = sceneNumber;
 1037        }
 38
 39        public void OnComponentCreated(IParcelScene scene, IDCLEntity entity)
 40        {
 1041            this.scene = scene;
 1042            audioSource = entity.gameObject.AddComponent<AudioSource>();
 1043            audioSource.spatialBlend = 1;
 1044            audioSource.dopplerLevel = 0.1f;
 45
 1046            if (settings != null)
 1047                settings.audioSettings.OnChanged += OnAudioSettingsChanged;
 48
 1049            dataStore.sceneBoundariesChecker.Add(entity,this);
 1050            dataStore.virtualAudioMixer.sceneSFXVolume.OnChange += OnVirtualAudioMixerChangedValue;
 1051            sceneNumber.OnChange += OnCurrentSceneChanged;
 1052        }
 53
 54        public void OnComponentRemoved(IParcelScene scene, IDCLEntity entity)
 55        {
 1156            Dispose(entity);
 1157        }
 58
 59        public void OnComponentModelUpdated(IParcelScene scene, IDCLEntity entity, PBAudioSource model)
 60        {
 1361            bool isSameClip = model.AudioClipUrl == this.model?.AudioClipUrl;
 1362            this.model = model;
 63
 64            // If the clip has changed, we need to forget the old clip
 1365            if (!isSameClip && promiseAudioClip != null)
 66            {
 067                isAudioClipReady = false;
 068                if (audioClip != null)
 069                    dataStore.sceneWorldObjects.RemoveAudioClip(scene.sceneData.sceneNumber, audioClip);
 070                DisposePromise();
 71            }
 72
 1373            ApplyCurrentModel();
 74
 1375            if (!isAudioClipReady && !isSameClip)
 76            {
 1077                promiseAudioClip = new AssetPromise_AudioClip(model.AudioClipUrl, scene.contentProvider);
 1078                promiseAudioClip.OnSuccessEvent += OnAudioClipLoadComplete;
 1079                promiseAudioClip.OnFailEvent += OnAudioClipLoadFail;
 80
 1081                keeperAudioClip.Keep(promiseAudioClip);
 82            }
 1383        }
 84
 85        void IOutOfSceneBoundariesHandler.UpdateOutOfBoundariesState(bool isInsideBoundaries)
 86        {
 087            if (scene.isPersistent)
 088                isInsideBoundaries = true;
 89
 090            isOutOfBoundaries = !isInsideBoundaries;
 091            UpdateAudioSourceVolume();
 092        }
 93
 94        private void DisposePromise()
 95        {
 1196            if (promiseAudioClip == null)
 097                return;
 98
 1199            promiseAudioClip.OnSuccessEvent += OnAudioClipLoadComplete;
 11100            promiseAudioClip.OnFailEvent += OnAudioClipLoadFail;
 101
 11102            keeperAudioClip.Forget(promiseAudioClip);
 11103        }
 104        private void Dispose(IDCLEntity entity)
 105        {
 11106            DisposePromise();
 107
 11108            if (audioClip != null)
 0109                dataStore.sceneWorldObjects.RemoveAudioClip(scene.sceneData.sceneNumber, audioClip);
 11110            dataStore.sceneBoundariesChecker.Remove(entity,this);
 111
 11112            sceneNumber.OnChange -= OnCurrentSceneChanged;
 113
 11114            if (settings != null)
 11115                settings.audioSettings.OnChanged -= OnAudioSettingsChanged;
 116
 11117            dataStore.virtualAudioMixer.sceneSFXVolume.OnChange -= OnVirtualAudioMixerChangedValue;
 11118            if (audioSource != null)
 119            {
 10120                GameObject.Destroy(audioSource);
 10121                audioSource = null;
 122            }
 11123        }
 124
 125        private void ApplyCurrentModel()
 126        {
 13127            if (audioSource == null)
 128            {
 0129                Debug.LogWarning("AudioSource is null!.");
 0130                return;
 131            }
 132
 13133            UpdateAudioSourceVolume();
 13134            audioSource.loop = model.Loop;
 13135            audioSource.pitch = model.GetPitch();
 13136            audioSource.spatialBlend = 1;
 13137            audioSource.dopplerLevel = 0.1f;
 138
 13139            if (!model.Playing)
 140            {
 12141                if (audioSource.isPlaying)
 142                {
 8143                    audioSource.Stop();
 144                }
 145            }
 1146            else if(isAudioClipReady)
 147            {
 0148                audioSource.Play();
 149            }
 5150        }
 151
 152        private void ApplyLoadedAudioClip(AudioClip clip)
 153        {
 1154            isAudioClipReady = true;
 1155            if (audioSource.clip != clip)
 1156                audioSource.clip = clip;
 157
 1158            bool shouldPlay = model.Playing && !audioSource.isPlaying;
 159
 1160            if (audioSource.enabled && model.Playing && shouldPlay)
 1161                audioSource.Play();
 1162        }
 163
 164        private void OnAudioClipLoadComplete(Asset_AudioClip assetAudioClip)
 165        {
 1166            if (assetAudioClip.audioClip == null)
 0167                return;
 168
 1169            audioClip = assetAudioClip.audioClip;
 170
 1171            dataStore.sceneWorldObjects.AddAudioClip(scene.sceneData.sceneNumber, audioClip);
 172
 1173            ApplyLoadedAudioClip(assetAudioClip.audioClip);
 1174        }
 175
 176        private void OnAudioClipLoadFail(Asset_AudioClip assetAudioClip, Exception exception)
 177        {
 0178            Debug.LogError("Audio clip couldn't be loaded. Url: " +model.AudioClipUrl + "     error: " + exception.Messa
 0179            DisposePromise();
 0180        }
 181
 182        private void OnAudioSettingsChanged(AudioSettings settings)
 183        {
 0184            UpdateAudioSourceVolume();
 0185        }
 186
 187        private void OnVirtualAudioMixerChangedValue(float currentValue, float previousValue)
 188        {
 0189            UpdateAudioSourceVolume();
 0190        }
 191
 192        private void UpdateAudioSourceVolume()
 193        {
 13194            float newVolume = 0;
 195
 196            // isOutOfBoundaries will always be false for global scenes.
 13197            if (!isOutOfBoundaries)
 198            {
 13199                AudioSettings audioSettingsData =
 200                    settings != null ? settings.audioSettings.Data : new AudioSettings();
 13201                newVolume = model.GetVolume() * Utils.ToVolumeCurve(
 202                    dataStore.virtualAudioMixer.sceneSFXVolume.Get() * audioSettingsData.sceneSFXVolume *
 203                    audioSettingsData.masterVolume);
 204            }
 205
 13206            bool isCurrentScene = scene.isPersistent || scene.sceneData.sceneNumber == sceneNumber.Get();
 207
 13208            audioSource.volume = isCurrentScene ? newVolume : 0f;
 13209        }
 210
 211        private void OnCurrentSceneChanged(int currentSceneNumber, int previousSceneNumber)
 212        {
 7213            if (audioSource == null || model == null)
 4214                return;
 215
 3216            float volume = 0;
 217
 3218            if (scene.isPersistent || scene.sceneData.sceneNumber == currentSceneNumber)
 2219                volume = model.GetVolume();
 220
 3221            audioSource.volume = volume;
 3222        }
 223    }
 224}