< Summary

Class:DCL.NavmapZoomViewController
Assembly:Navmap
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/NavMap/NavmapZoomViewController.cs
Covered lines:23
Uncovered lines:71
Coverable lines:94
Total lines:208
Line coverage:24.4% (23 of 94)
Covered branches:0
Total branches:0
Covered methods:3
Total methods:13
Method coverage:23% (3 of 13)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
NavmapZoomViewController(...)0%22090%
OnFeatureFlagsChanged(...)0%2100%
HandleFeatureFlag()0%6200%
Dispose()0%110100%
CurveClamp01()0%440100%
ResetZoomToMidValue()0%2100%
Activate(...)0%12300%
Deactivate()0%6200%
OnMouseWheelValueChanged(...)0%30500%
SetZoomLevel(...)0%2100%
Zoom(...)0%90900%
SetUiButtonsInteractivity()0%2100%
ScaleOverTime()0%30500%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/NavMap/NavmapZoomViewController.cs

#LineLine coverage
 1using Cysharp.Threading.Tasks;
 2using DCL.Tasks;
 3using DCLServices.MapRendererV2.MapCameraController;
 4using System;
 5using System.Threading;
 6using UnityEngine;
 7using UnityEngine.EventSystems;
 8
 9namespace DCL
 10{
 11    public class NavmapZoomViewController : IDisposable, INavmapZoomViewController
 12    {
 13        private const float MOUSE_WHEEL_THRESHOLD = 0.04f;
 14
 15        private readonly NavmapZoomView view;
 16
 17        private AnimationCurve normalizedCurve;
 18        private int zoomSteps;
 19
 20        private bool active;
 21
 22        private CancellationTokenSource cts;
 23        private bool isScaling;
 24
 25        private float targetNormalizedZoom;
 26        private int currentZoomLevel;
 27
 28        private IMapCameraController cameraController;
 29        private readonly BaseVariable<FeatureFlag> featureFlagsFlags;
 30
 131        public NavmapZoomViewController(NavmapZoomView view, BaseVariable<FeatureFlag> featureFlagsFlags)
 32        {
 133            this.view = view;
 134            this.featureFlagsFlags = featureFlagsFlags;
 35
 136            if (featureFlagsFlags.Get().IsInitialized)
 037                HandleFeatureFlag();
 38            else
 139                featureFlagsFlags.OnChange += OnFeatureFlagsChanged;
 40
 141            normalizedCurve = view.normalizedZoomCurve;
 142            zoomSteps = normalizedCurve.length;
 43
 144            CurveClamp01();
 145        }
 46
 47        private void OnFeatureFlagsChanged(FeatureFlag current, FeatureFlag previous)
 48        {
 049            featureFlagsFlags.OnChange -= OnFeatureFlagsChanged;
 050            HandleFeatureFlag();
 051        }
 52
 53        private void HandleFeatureFlag()
 54        {
 055            if (featureFlagsFlags.Get().IsFeatureEnabled("map_focus_home_or_user")) return;
 56
 057            view.zoomVerticalRange = new Vector2Int(view.zoomVerticalRange.x, 40);
 58
 059            normalizedCurve = new AnimationCurve();
 060            normalizedCurve.AddKey(0, 0);
 061            normalizedCurve.AddKey(1, 0.25f);
 062            normalizedCurve.AddKey(2, 0.5f);
 063            normalizedCurve.AddKey(3, 0.75f);
 064            normalizedCurve.AddKey(4, 1);
 065            zoomSteps = normalizedCurve.length;
 066        }
 67
 68        public void Dispose()
 69        {
 170            cts.SafeCancelAndDispose();
 171        }
 72
 73        private void CurveClamp01()
 74        {
 75            // Keys should be int for zoomSteps to work properly
 1676            for (var i = 0; i < normalizedCurve.keys.Length; i++)
 77            {
 778                Keyframe keyFrame = normalizedCurve.keys[i];
 79
 780                if (i == 0)
 81                {
 182                    keyFrame.time = 0;
 183                    keyFrame.value = 0;
 84                }
 685                else if (i == normalizedCurve.length - 1)
 86                {
 187                    keyFrame.time = Mathf.RoundToInt(keyFrame.time);
 188                    keyFrame.value = 1;
 89                }
 90                else
 91                {
 592                    keyFrame.time = Mathf.RoundToInt(keyFrame.time);
 593                    keyFrame.value = keyFrame.value;
 94                }
 95
 796                normalizedCurve.MoveKey(i, keyFrame);
 97            }
 198        }
 99
 100        public float ResetZoomToMidValue()
 101        {
 0102            SetZoomLevel(Mathf.FloorToInt((zoomSteps - 1) / 2f));
 0103            return targetNormalizedZoom;
 104        }
 105
 106        public void Activate(IMapCameraController mapCameraController)
 107        {
 0108            if (active)
 109            {
 0110                if (cameraController == mapCameraController)
 0111                    return;
 112
 0113                Deactivate();
 114            }
 115
 0116            cts = new CancellationTokenSource();
 117
 0118            cameraController = mapCameraController;
 119
 0120            view.MouseWheelAction.OnValueChanged += OnMouseWheelValueChanged;
 0121            view.ZoomIn.InputAction.OnStarted += Zoom;
 0122            view.ZoomOut.InputAction.OnStarted += Zoom;
 0123            view.ZoomIn.Button.onClick.AddListener(() => Zoom(DCLAction_Hold.ZoomIn));
 0124            view.ZoomOut.Button.onClick.AddListener(() => Zoom(DCLAction_Hold.ZoomOut));
 125
 0126            active = true;
 0127        }
 128
 129        public void Deactivate()
 130        {
 0131            if (!active) return;
 132
 0133            cts.Cancel();
 0134            cts.Dispose();
 0135            cts = null;
 136
 0137            view.MouseWheelAction.OnValueChanged -= OnMouseWheelValueChanged;
 0138            view.ZoomIn.InputAction.OnStarted -= Zoom;
 0139            view.ZoomOut.InputAction.OnStarted -= Zoom;
 0140            view.ZoomIn.Button.onClick.RemoveAllListeners();
 0141            view.ZoomOut.Button.onClick.RemoveAllListeners();
 142
 0143            active = false;
 0144        }
 145
 146        private void OnMouseWheelValueChanged(DCLAction_Measurable action, float value)
 147        {
 0148            if (value == 0 || Mathf.Abs(value) < MOUSE_WHEEL_THRESHOLD)
 0149                return;
 150
 0151            DCLAction_Hold zoomAction = value > 0 ? DCLAction_Hold.ZoomIn : DCLAction_Hold.ZoomOut;
 0152            Zoom(zoomAction);
 0153        }
 154
 155        private void SetZoomLevel(int zoomLevel)
 156        {
 0157            currentZoomLevel = Mathf.Clamp(zoomLevel, 0, zoomSteps - 1);
 0158            targetNormalizedZoom = normalizedCurve.Evaluate(currentZoomLevel);
 159
 0160            SetUiButtonsInteractivity();
 0161        }
 162
 163        private void Zoom(DCLAction_Hold action)
 164        {
 0165            if (!active || isScaling)
 0166                return;
 167
 0168            EventSystem.current.SetSelectedGameObject(null);
 169
 0170            switch (action)
 171            {
 0172                case DCLAction_Hold.ZoomIn when Mathf.Approximately(targetNormalizedZoom, 1f):
 0173                case DCLAction_Hold.ZoomOut when Mathf.Approximately(targetNormalizedZoom, 0f):
 0174                    return;
 175            }
 176
 0177            SetZoomLevel(currentZoomLevel + (action == DCLAction_Hold.ZoomIn ? 1 : -1));
 0178            ScaleOverTime(cameraController.Zoom, targetNormalizedZoom, cts.Token).Forget();
 179
 0180            SetUiButtonsInteractivity();
 0181        }
 182
 183        private void SetUiButtonsInteractivity()
 184        {
 0185            view.ZoomIn.SetUiInteractable(isInteractable: currentZoomLevel < zoomSteps - 1);
 0186            view.ZoomOut.SetUiInteractable(isInteractable: currentZoomLevel > 0);
 0187        }
 188
 189        private async UniTaskVoid ScaleOverTime(float from, float to, CancellationToken ct)
 190        {
 0191            isScaling = true;
 0192            float scaleDuration = view.scaleDuration;
 193
 0194            for (float timer = 0; timer < scaleDuration; timer += Time.deltaTime)
 195            {
 0196                if (ct.IsCancellationRequested)
 197                    break;
 198
 0199                cameraController.SetZoom(Mathf.Lerp(from, to, timer / scaleDuration));
 200
 201                // omit CT, handle cancellation gracefully
 0202                await UniTask.NextFrame();
 203            }
 204
 0205            isScaling = false;
 0206        }
 207    }
 208}