< Summary

Class:DCL.ECSComponents.ECSAudioStreamComponentHandler
Assembly:DCL.ECSComponents.AudioStream
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/AudioStream/ECSAudioStreamComponentHandler.cs
Covered lines:46
Uncovered lines:26
Coverable lines:72
Total lines:176
Line coverage:63.8% (46 of 72)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ECSAudioStreamComponentHandler()0%110100%
OnComponentCreated(...)0%440100%
OnComponentRemoved(...)0%110100%
OnComponentModelUpdated(...)0%3.033085.71%
Dispose()0%220100%
UpdateModel(...)0%110100%
StateHasChange(...)0%330100%
ConditionsToPlayChanged()0%30500%
CanAudioStreamBePlayed()0%330100%
OnSceneChanged(...)0%2100%
OnRendererStateChanged(...)0%2100%
OnSettingsChanged(...)0%6200%
GetCalculatedSettingsVolume(...)0%110100%
SceneSFXVolume_OnChange(...)0%2100%
StopStreaming()0%110100%
StartStreaming()0%2100%
SendUpdateAudioStreamEvent(...)0%110100%
OnCursorLockChanged(...)0%6200%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/AudioStream/ECSAudioStreamComponentHandler.cs

#LineLine coverage
 1using System;
 2using DCL.Controllers;
 3using DCL.ECSRuntime;
 4using DCL.Helpers;
 5using DCL.Interface;
 6using DCL.Models;
 7using DCL.SettingsCommon;
 8using UnityEngine;
 9using AudioSettings = DCL.SettingsCommon.AudioSettings;
 10
 11namespace DCL.ECSComponents
 12{
 13    public class ECSAudioStreamComponentHandler : IECSComponentHandler<PBAudioStream>
 14    {
 15        private float settingsVolume = 0;
 16
 617        internal float currentVolume = -1;
 18        internal bool isPlaying = false;
 19        internal PBAudioStream model;
 20        internal IParcelScene scene;
 21
 22        // Flags to check if we can activate the AudioStream
 23        internal bool isInsideScene = false;
 24        internal bool isRendererActive = false;
 25        internal bool wasCursorLocked = false;
 26
 27        public void OnComponentCreated(IParcelScene scene, IDCLEntity entity)
 28        {
 629            this.scene = scene;
 30
 31            // If it is a smart wearable, we don't look up to see if the scene has changed since the scene is global
 632            if (!scene.isPersistent)
 633                CommonScriptableObjects.sceneNumber.OnChange += OnSceneChanged;
 34
 635            CommonScriptableObjects.rendererState.OnChange += OnRendererStateChanged;
 636            Settings.i.audioSettings.OnChanged += OnSettingsChanged;
 637            DataStore.i.virtualAudioMixer.sceneSFXVolume.OnChange += SceneSFXVolume_OnChange;
 638            settingsVolume = GetCalculatedSettingsVolume(Settings.i.audioSettings.Data);
 39
 640            isRendererActive = CommonScriptableObjects.rendererState.Get();
 641            isInsideScene = scene.isPersistent || scene.sceneData.sceneNumber == CommonScriptableObjects.sceneNumber.Get
 42
 643            wasCursorLocked = Utils.IsCursorLocked;
 644            if (!wasCursorLocked)
 45            {
 646                Utils.OnCursorLockChanged += OnCursorLockChanged;
 47            }
 648        }
 49
 50        public void OnComponentRemoved(IParcelScene scene, IDCLEntity entity)
 51        {
 652            Utils.OnCursorLockChanged -= OnCursorLockChanged;
 653            Dispose();
 654        }
 55
 56        public void OnComponentModelUpdated(IParcelScene scene, IDCLEntity entity, PBAudioStream model)
 57        {
 58            // Nothing has change so we do an early return
 959            if (!StateHasChange(model))
 060                return;
 61
 62            // We update the model and the volume
 963            UpdateModel(model);
 64
 65            // In case that the audio stream can't be played we do an early return
 966            if (!CanAudioStreamBePlayed())
 667                return;
 68
 69            // If everything went ok, we update the state
 370            SendUpdateAudioStreamEvent(model.Playing);
 371        }
 72
 73        private void Dispose()
 74        {
 675            if(!scene.isPersistent)
 676                CommonScriptableObjects.sceneNumber.OnChange -= OnSceneChanged;
 77
 678            CommonScriptableObjects.rendererState.OnChange -= OnRendererStateChanged;
 679            Settings.i.audioSettings.OnChanged -= OnSettingsChanged;
 680            DataStore.i.virtualAudioMixer.sceneSFXVolume.OnChange -= SceneSFXVolume_OnChange;
 81
 682            StopStreaming();
 683        }
 84
 85        private void UpdateModel(PBAudioStream model)
 86        {
 987            this.model = model;
 988            currentVolume = model.GetVolume() * settingsVolume;
 989        }
 90
 91        private bool StateHasChange(PBAudioStream model)
 92        {
 93            // First time that the model come so the state has change
 994            if (this.model == null)
 695                return true;
 96
 397            bool shouldChangeState = isPlaying && !model.Playing;
 398            bool shouldUpdateVolume = Mathf.Approximately(currentVolume, model.GetVolume());
 399            bool shouldUpdateUrl = this.model.Url == model.Url;
 100
 3101            return shouldChangeState || shouldUpdateVolume || shouldUpdateUrl;
 102        }
 103
 104        private void ConditionsToPlayChanged()
 105        {
 0106            bool canBePlayed = CanAudioStreamBePlayed();
 107
 0108            if (isPlaying && !canBePlayed)
 0109                StopStreaming();
 0110            if (!isPlaying && canBePlayed && model.Playing)
 0111                StartStreaming();
 0112        }
 113
 114        private bool CanAudioStreamBePlayed()
 115        {
 9116            return isInsideScene && isRendererActive && wasCursorLocked;
 117        }
 118
 119        private void OnSceneChanged(int sceneNumber, int prevSceneNumber)
 120        {
 0121            isInsideScene = sceneNumber == scene.sceneData.sceneNumber;
 0122            ConditionsToPlayChanged();
 0123        }
 124
 125        private void OnRendererStateChanged(bool isEnable, bool prevState)
 126        {
 0127            isRendererActive = isEnable;
 0128            ConditionsToPlayChanged();
 0129        }
 130
 131        private void OnSettingsChanged(AudioSettings settings)
 132        {
 0133            float newSettingsVolume = GetCalculatedSettingsVolume(settings);
 0134            if (Math.Abs(settingsVolume - newSettingsVolume) > Mathf.Epsilon)
 135            {
 0136                settingsVolume = newSettingsVolume;
 0137                SendUpdateAudioStreamEvent(isPlaying);
 138            }
 0139        }
 140
 141        private float GetCalculatedSettingsVolume(AudioSettings audioSettings)
 142        {
 6143            return Utils.ToVolumeCurve(DataStore.i.virtualAudioMixer.sceneSFXVolume.Get() * audioSettings.sceneSFXVolume
 144        }
 145
 146        private void SceneSFXVolume_OnChange(float current, float previous)
 147        {
 0148            OnSettingsChanged(Settings.i.audioSettings.Data);
 0149        }
 150
 151        private void StopStreaming()
 152        {
 6153            SendUpdateAudioStreamEvent(false);
 6154        }
 155
 156        private void StartStreaming()
 157        {
 0158            SendUpdateAudioStreamEvent(true);
 0159        }
 160
 161        private void SendUpdateAudioStreamEvent(bool play)
 162        {
 9163            isPlaying = play;
 9164            WebInterface.SendAudioStreamEvent(model.Url, isPlaying, currentVolume);
 9165        }
 166
 167        private void OnCursorLockChanged(bool isLocked)
 168        {
 0169            if (isLocked)
 170            {
 0171                wasCursorLocked = true;
 0172                ConditionsToPlayChanged();
 173            }
 0174        }
 175    }
 176}