< Summary

Class:DCLServices.MapRendererV2.ConsumerUtils.MapCameraDragBehavior
Assembly:MapRendererConsumerUtils
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLServices/MapRendererV2/ConsumerUtils/MapCameraDragBehavior.cs
Covered lines:11
Uncovered lines:50
Coverable lines:61
Total lines:149
Line coverage:18% (11 of 61)
Covered branches:0
Total branches:0
Covered methods:4
Total methods:12
Method coverage:33.3% (4 of 12)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
MapCameraDragBehavior()0%110100%
MapCameraDragBehavior(...)0%110100%
Activate(...)0%2100%
Deactivate()0%2100%
OnBeginDrag(...)0%12300%
OnDrag(...)0%6200%
OnEndDrag(...)0%6200%
StopInertia()0%330100%
InertiaLoop()0%90900%
Dispose()0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLServices/MapRendererV2/ConsumerUtils/MapCameraDragBehavior.cs

#LineLine coverage
 1using Cysharp.Threading.Tasks;
 2using DCLServices.MapRendererV2.MapCameraController;
 3using System;
 4using System.Threading;
 5using UnityEngine;
 6using UnityEngine.EventSystems;
 7
 8namespace DCLServices.MapRendererV2.ConsumerUtils
 9{
 10    public class MapCameraDragBehavior : IDisposable
 11    {
 12        [Serializable]
 13        public class MapCameraDragBehaviorData
 14        {
 15            [SerializeField] internal bool inertia;
 16            [SerializeField] internal float decelerationRate;
 17        }
 18
 119        private static Vector3[] worldCorners = new Vector3[4];
 20
 021        internal bool dragging { get; private set; }
 22
 23        private readonly RectTransform rectTransform;
 24        private readonly MapCameraDragBehaviorData data;
 25
 26        private IMapCameraController mapCameraController;
 27
 28        private Vector2 pointerPositionOnDragBegin;
 29        private Vector2 cameraPositionOnDragBegin;
 30
 31        private float screenSpaceToLocalCameraPositionRatio;
 32
 33        private CancellationTokenSource inertiaLoopCTS;
 34
 135        public MapCameraDragBehavior(RectTransform rectTransform, MapCameraDragBehaviorData data)
 36        {
 137            this.rectTransform = rectTransform;
 138            this.data = data;
 139        }
 40
 41        public void Activate(IMapCameraController cameraController)
 42        {
 043            mapCameraController = cameraController;
 044        }
 45
 46        public void Deactivate()
 47        {
 048            mapCameraController = null;
 049            dragging = false;
 50
 051            StopInertia();
 052        }
 53
 54        public void OnBeginDrag(PointerEventData eventData)
 55        {
 056            if (eventData.button != PointerEventData.InputButton.Left)
 057                return;
 58
 059            rectTransform.GetWorldCorners(worldCorners);
 60
 061            Vector2 bottomLeft = RectTransformUtility.WorldToScreenPoint(eventData.pressEventCamera, worldCorners[0]);
 062            Vector2 topRight = RectTransformUtility.WorldToScreenPoint(eventData.pressEventCamera, worldCorners[2]);
 63
 064            screenSpaceToLocalCameraPositionRatio = mapCameraController.GetVerticalSizeInLocalUnits() / (topRight - bott
 65
 066            pointerPositionOnDragBegin = eventData.position;
 067            cameraPositionOnDragBegin = mapCameraController.LocalPosition;
 68
 069            dragging = true;
 70
 071            if (data.inertia)
 72            {
 073                StopInertia();
 074                inertiaLoopCTS = new CancellationTokenSource();
 075                InertiaLoop(inertiaLoopCTS.Token).Forget();
 76            }
 077        }
 78
 79        public void OnDrag(PointerEventData eventData)
 80        {
 081            if (eventData.button != PointerEventData.InputButton.Left)
 082                return;
 83
 084            var pointerPosition = eventData.position;
 85
 086            var pointerDelta = pointerPosition - pointerPositionOnDragBegin;
 087            var targetCameraLocalPosition = cameraPositionOnDragBegin - (pointerDelta * screenSpaceToLocalCameraPosition
 88
 089            mapCameraController.SetLocalPosition(targetCameraLocalPosition);
 090        }
 91
 92        public void OnEndDrag(PointerEventData eventData)
 93        {
 094            if (eventData.button != PointerEventData.InputButton.Left)
 095                return;
 96
 097            dragging = false;
 098        }
 99
 100        private void StopInertia()
 101        {
 1102            inertiaLoopCTS?.Cancel();
 1103            inertiaLoopCTS?.Dispose();
 1104            inertiaLoopCTS = null;
 1105        }
 106
 107        private async UniTaskVoid InertiaLoop(CancellationToken ct)
 108        {
 0109            var prevPosition = mapCameraController.LocalPosition;
 0110            var inertialVelocity = Vector2.zero;
 111
 0112            while (true)
 113            {
 0114                await UniTask.NextFrame(PlayerLoopTiming.PostLateUpdate);
 0115                if (ct.IsCancellationRequested) break;
 0116                float unscaledDeltaTime = Time.unscaledDeltaTime;
 0117                var cameraLocalPos = mapCameraController.LocalPosition;
 118
 0119                if (dragging)
 120                {
 0121                    var newVelocity = (cameraLocalPos - prevPosition) / unscaledDeltaTime;
 0122                    inertialVelocity = Vector2.Lerp(inertialVelocity, newVelocity, unscaledDeltaTime * 10);
 123                }
 124                else
 125                {
 0126                    for (var axis = 0; axis < 2; axis++)
 127                    {
 0128                        inertialVelocity[axis] *= Mathf.Pow(this.data.decelerationRate, unscaledDeltaTime);
 129
 0130                        if (Mathf.Abs(inertialVelocity[axis]) < 1)
 0131                            inertialVelocity[axis] = 0;
 132                    }
 133
 0134                    mapCameraController.SetLocalPosition(cameraLocalPos + (inertialVelocity * unscaledDeltaTime));
 135
 0136                    if (Mathf.Approximately(inertialVelocity.x, 0) && Mathf.Approximately(inertialVelocity.y, 0))
 137                        break;
 138                }
 139
 0140                prevPosition = cameraLocalPos;
 141            }
 0142        }
 143
 144        public void Dispose()
 145        {
 1146            StopInertia();
 1147        }
 148    }
 149}