< 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:45
Uncovered lines:27
Coverable lines:72
Total lines:178
Line coverage:62.5% (45 of 72)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ECSAudioStreamComponentHandler()0%2100%
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
 017        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            // If it is a smart wearable, we don't look up to see if the scene has change since the scene is global
 631            if (!scene.isPersistent)
 32            {
 633                CommonScriptableObjects.sceneID.OnChange += OnSceneChanged;
 34            }
 35
 636            CommonScriptableObjects.rendererState.OnChange += OnRendererStateChanged;
 637            Settings.i.audioSettings.OnChanged += OnSettingsChanged;
 638            DataStore.i.virtualAudioMixer.sceneSFXVolume.OnChange += SceneSFXVolume_OnChange;
 639            settingsVolume = GetCalculatedSettingsVolume(Settings.i.audioSettings.Data);
 40
 641            isRendererActive = CommonScriptableObjects.rendererState.Get();
 642            isInsideScene = scene.isPersistent || scene.sceneData.id == CommonScriptableObjects.sceneID.Get();
 43
 644            wasCursorLocked = Utils.IsCursorLocked;
 645            if (!wasCursorLocked)
 46            {
 647                Utils.OnCursorLockChanged += OnCursorLockChanged;
 48            }
 649        }
 50
 51        public void OnComponentRemoved(IParcelScene scene, IDCLEntity entity)
 52        {
 653            Utils.OnCursorLockChanged -= OnCursorLockChanged;
 654            Dispose();
 655        }
 56
 57        public void OnComponentModelUpdated(IParcelScene scene, IDCLEntity entity, PBAudioStream model)
 58        {
 59            // Nothing has change so we do an early return
 960            if (!StateHasChange(model))
 061                return;
 62
 63            // We update the model and the volume
 964            UpdateModel(model);
 65
 66            // In case that the audio stream can't be played we do an early return
 967            if (!CanAudioStreamBePlayed())
 668                return;
 69
 70            // If everything went ok, we update the state
 371            SendUpdateAudioStreamEvent(model.Playing);
 372        }
 73
 74        private void Dispose()
 75        {
 676            if (!scene.isPersistent)
 77            {
 678                CommonScriptableObjects.sceneID.OnChange -= OnSceneChanged;
 79            }
 680            CommonScriptableObjects.rendererState.OnChange -= OnRendererStateChanged;
 681            Settings.i.audioSettings.OnChanged -= OnSettingsChanged;
 682            DataStore.i.virtualAudioMixer.sceneSFXVolume.OnChange -= SceneSFXVolume_OnChange;
 83
 684            StopStreaming();
 685        }
 86
 87        private void UpdateModel(PBAudioStream model)
 88        {
 989            this.model = model;
 990            currentVolume = model.GetVolume() * settingsVolume;
 991        }
 92
 93        private bool StateHasChange(PBAudioStream model)
 94        {
 95            // First time that the model come so the state has change
 996            if (this.model == null)
 697                return true;
 98
 399            bool shouldChangeState = isPlaying && !model.Playing;
 3100            bool shouldUpdateVolume = Mathf.Approximately(currentVolume, model.GetVolume());
 3101            bool shouldUpdateUrl = this.model.Url == model.Url;
 102
 3103            return shouldChangeState || shouldUpdateVolume || shouldUpdateUrl;
 104        }
 105
 106        private void ConditionsToPlayChanged()
 107        {
 0108            bool canBePlayed = CanAudioStreamBePlayed();
 109
 0110            if (isPlaying && !canBePlayed)
 0111                StopStreaming();
 0112            if (!isPlaying && canBePlayed && model.Playing)
 0113                StartStreaming();
 0114        }
 115
 116        private bool CanAudioStreamBePlayed()
 117        {
 9118            return isInsideScene && isRendererActive && wasCursorLocked;
 119        }
 120
 121        private void OnSceneChanged(string sceneId, string prevSceneId)
 122        {
 0123            isInsideScene = sceneId == scene.sceneData.id;
 0124            ConditionsToPlayChanged();
 0125        }
 126
 127        private void OnRendererStateChanged(bool isEnable, bool prevState)
 128        {
 0129            isRendererActive = isEnable;
 0130            ConditionsToPlayChanged();
 0131        }
 132
 133        private void OnSettingsChanged(AudioSettings settings)
 134        {
 0135            float newSettingsVolume = GetCalculatedSettingsVolume(settings);
 0136            if (Math.Abs(settingsVolume - newSettingsVolume) > Mathf.Epsilon)
 137            {
 0138                settingsVolume = newSettingsVolume;
 0139                SendUpdateAudioStreamEvent(isPlaying);
 140            }
 0141        }
 142
 143        private float GetCalculatedSettingsVolume(AudioSettings audioSettings)
 144        {
 6145            return Utils.ToVolumeCurve(DataStore.i.virtualAudioMixer.sceneSFXVolume.Get() * audioSettings.sceneSFXVolume
 146        }
 147
 148        private void SceneSFXVolume_OnChange(float current, float previous)
 149        {
 0150            OnSettingsChanged(Settings.i.audioSettings.Data);
 0151        }
 152
 153        private void StopStreaming()
 154        {
 6155            SendUpdateAudioStreamEvent(false);
 6156        }
 157
 158        private void StartStreaming()
 159        {
 0160            SendUpdateAudioStreamEvent(true);
 0161        }
 162
 163        private void SendUpdateAudioStreamEvent(bool play)
 164        {
 9165            isPlaying = play;
 9166            WebInterface.SendAudioStreamEvent(model.Url, isPlaying, currentVolume);
 9167        }
 168
 169        private void OnCursorLockChanged(bool isLocked)
 170        {
 0171            if (isLocked)
 172            {
 0173                wasCursorLocked = true;
 0174                ConditionsToPlayChanged();
 175            }
 0176        }
 177    }
 178}