< Summary

Class:ECSTweenHandler
Assembly:DCL.ECSComponents.Tween
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/Tween/ECSTweenHandler.cs
Covered lines:60
Uncovered lines:8
Coverable lines:68
Total lines:201
Line coverage:88.2% (60 of 68)
Covered branches:0
Total branches:0
Covered methods:8
Total methods:9
Method coverage:88.8% (8 of 9)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ECSTweenHandler()0%110100%
ECSTweenHandler(...)0%110100%
OnComponentCreated(...)0%2100%
OnComponentRemoved(...)0%110100%
OnComponentModelUpdated(...)0%14.1614090.62%
AreSameModels(...)0%35.517060%
SetupRotationTween(...)0%110100%
SetupScaleTween(...)0%110100%
SetupPositionTween(...)0%220100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/Tween/ECSTweenHandler.cs

#LineLine coverage
 1using DCL.Controllers;
 2using DCL.ECS7.InternalComponents;
 3using DCL.ECSComponents;
 4using DCL.ECSRuntime;
 5using DCL.Models;
 6using DG.Tweening;
 7using System.Collections.Generic;
 8using UnityEngine;
 9using static DCL.ECSComponents.EasingFunction;
 10using static DG.Tweening.Ease;
 11
 12public class ECSTweenHandler : IECSComponentHandler<PBTween>
 13{
 114    private static readonly Dictionary<EasingFunction, Ease> easingFunctionsMap = new Dictionary<EasingFunction,Ease>()
 15    {
 16        [EfLinear] = Linear,
 17        [EfEaseinsine] = InSine,
 18        [EfEaseoutsine] = OutSine,
 19        [EfEasesine] = InOutSine,
 20        [EfEaseinquad] = InQuad,
 21        [EfEaseoutquad] = OutQuad,
 22        [EfEasequad] = InOutQuad,
 23        [EfEaseinexpo] = InExpo,
 24        [EfEaseoutexpo] = OutExpo,
 25        [EfEaseexpo] = InOutExpo,
 26        [EfEaseinelastic] = InElastic,
 27        [EfEaseoutelastic] = OutElastic,
 28        [EfEaseelastic] = InOutElastic,
 29        [EfEaseinbounce] = InBounce,
 30        [EfEaseoutbounce] = OutBounce,
 31        [EfEasebounce] = InOutBounce,
 32        [EfEaseincubic] = InCubic,
 33        [EfEaseoutcubic] = OutCubic,
 34        [EfEasecubic] = InOutCubic,
 35        [EfEaseinquart] = InQuart,
 36        [EfEaseoutquart] = OutQuart,
 37        [EfEasequart] = InOutQuart,
 38        [EfEaseinquint] = InQuint,
 39        [EfEaseoutquint] = OutQuint,
 40        [EfEasequint] = InOutQuint,
 41        [EfEaseincirc] = InCirc,
 42        [EfEaseoutcirc] = OutCirc,
 43        [EfEasecirc] = InOutCirc,
 44        [EfEaseinback] = InBack,
 45        [EfEaseoutback] = OutBack,
 46        [EfEaseback] = InOutBack
 47    };
 48
 49    private readonly IInternalECSComponent<InternalTween> internalTweenComponent;
 50    private readonly IInternalECSComponent<InternalSceneBoundsCheck> sbcInternalComponent;
 51    private Tweener currentTweener;
 52
 1453    public ECSTweenHandler(IInternalECSComponent<InternalTween> internalTweenComponent, IInternalECSComponent<InternalSc
 54    {
 1455        this.internalTweenComponent = internalTweenComponent;
 1456        this.sbcInternalComponent = sbcInternalComponent;
 1457    }
 58
 059    public void OnComponentCreated(IParcelScene scene, IDCLEntity entity) { }
 60
 61    public void OnComponentRemoved(IParcelScene scene, IDCLEntity entity)
 62    {
 1563        currentTweener.Kill(false);
 1564        internalTweenComponent.RemoveFor(scene, entity, new InternalTween()
 65        {
 66            removed = true
 67        });
 68
 69        // SBC Internal Component is reset when the Transform component is removed, not here.
 1570    }
 71
 72    public void OnComponentModelUpdated(IParcelScene scene, IDCLEntity entity, PBTween model)
 73    {
 1874        if (model.ModeCase == PBTween.ModeOneofCase.None)
 075            return;
 76
 77        // by default it's playing
 1878        bool isPlaying = !model.HasPlaying || model.Playing;
 79
 1880        var internalComponentModel = internalTweenComponent.GetFor(scene, entity)?.model ?? new InternalTween();
 1881        if (!AreSameModels(model, internalComponentModel.lastModel))
 82        {
 1683            Transform entityTransform = entity.gameObject.transform;
 1684            float durationInSeconds = model.Duration / 1000;
 1685            currentTweener = internalComponentModel.tweener;
 86
 87            // There may be a tween running for the entity transform, even with internalComponentModel.tweener
 88            // as null, e.g: during preview mode hot-reload.
 1689            var transformTweens = DOTween.TweensByTarget(entityTransform, true);
 1690            transformTweens?[0].Rewind(false);
 91
 1692            internalComponentModel.transform = entityTransform;
 1693            internalComponentModel.currentTime = model.CurrentTime;
 94
 1695            if (!easingFunctionsMap.TryGetValue(model.EasingFunction, out Ease ease))
 096                ease = Ease.Linear;
 97
 1698            switch (model.ModeCase)
 99            {
 100                case PBTween.ModeOneofCase.Rotate:
 3101                    currentTweener = SetupRotationTween(scene, entity,
 102                        ProtoConvertUtils.PBQuaternionToUnityQuaternion(model.Rotate.Start),
 103                        ProtoConvertUtils.PBQuaternionToUnityQuaternion(model.Rotate.End),
 104                        durationInSeconds, ease);
 3105                    break;
 106                case PBTween.ModeOneofCase.Scale:
 5107                    currentTweener = SetupScaleTween(scene, entity,
 108                        ProtoConvertUtils.PBVectorToUnityVector(model.Scale.Start),
 109                        ProtoConvertUtils.PBVectorToUnityVector(model.Scale.End),
 110                        durationInSeconds, ease);
 5111                    break;
 112                case PBTween.ModeOneofCase.Move:
 113                default:
 8114                    currentTweener = SetupPositionTween(scene, entity,
 115                        ProtoConvertUtils.PBVectorToUnityVector(model.Move.Start),
 116                        ProtoConvertUtils.PBVectorToUnityVector(model.Move.End),
 117                        durationInSeconds, ease, model.Move.HasFaceDirection && model.Move.FaceDirection);
 118                    break;
 119            }
 120
 16121            currentTweener.Goto(model.CurrentTime * durationInSeconds, isPlaying);
 16122            internalComponentModel.tweener = currentTweener;
 16123            internalComponentModel.tweenMode = model.ModeCase;
 124        }
 2125        else if (internalComponentModel.playing == isPlaying)
 126        {
 0127            return;
 128        }
 129
 18130        internalComponentModel.playing = isPlaying;
 131
 18132        if (isPlaying)
 17133            internalComponentModel.tweener.Play();
 134        else
 1135            internalComponentModel.tweener.Pause();
 136
 18137        internalComponentModel.lastModel = model;
 18138        internalTweenComponent.PutFor(scene, entity, internalComponentModel);
 18139    }
 140
 141    private static bool AreSameModels(PBTween modelA, PBTween modelB)
 142    {
 18143        if (modelB == null || modelA == null)
 14144            return false;
 145
 4146        if (modelB.ModeCase != modelA.ModeCase
 147            || modelB.EasingFunction != modelA.EasingFunction
 148            || !modelB.CurrentTime.Equals(modelA.CurrentTime)
 149            || !modelB.Duration.Equals(modelA.Duration))
 2150            return false;
 151
 2152        return modelA.ModeCase switch
 153               {
 0154                   PBTween.ModeOneofCase.Scale => modelB.Scale.Start.Equals(modelA.Scale.Start) && modelB.Scale.End.Equa
 0155                   PBTween.ModeOneofCase.Rotate => modelB.Rotate.Start.Equals(modelA.Rotate.Start) && modelB.Rotate.End.
 2156                   PBTween.ModeOneofCase.Move => modelB.Move.Start.Equals(modelA.Move.Start) && modelB.Move.End.Equals(m
 0157                   PBTween.ModeOneofCase.None => modelB.Move.Start.Equals(modelA.Move.Start) && modelB.Move.End.Equals(m
 0158                   _ => modelB.Move.Start.Equals(modelA.Move.Start) && modelB.Move.End.Equals(modelA.Move.End)
 159               };
 160    }
 161
 162    private Tweener SetupRotationTween(IParcelScene scene, IDCLEntity entity, Quaternion startRotation,
 163        Quaternion endRotation, float durationInSeconds, Ease ease)
 164    {
 3165        var entityTransform = entity.gameObject.transform;
 3166        entityTransform.localRotation = startRotation;
 3167        var tweener = entityTransform.DOLocalRotateQuaternion(endRotation, durationInSeconds).SetEase(ease).SetAutoKill(
 168
 3169        sbcInternalComponent.OnTransformScaleRotationChanged(scene, entity);
 170
 3171        return tweener;
 172    }
 173
 174    private Tweener SetupScaleTween(IParcelScene scene, IDCLEntity entity, Vector3 startScale,
 175        Vector3 endScale, float durationInSeconds, Ease ease)
 176    {
 5177        var entityTransform = entity.gameObject.transform;
 5178        entityTransform.localScale = startScale;
 5179        var tweener = entityTransform.DOScale(endScale, durationInSeconds).SetEase(ease).SetAutoKill(false);
 180
 5181        sbcInternalComponent.OnTransformScaleRotationChanged(scene, entity);
 182
 5183        return tweener;
 184    }
 185
 186    private Tweener SetupPositionTween(IParcelScene scene, IDCLEntity entity, Vector3 startPosition,
 187        Vector3 endPosition, float durationInSeconds, Ease ease, bool faceDirection)
 188    {
 8189        var entityTransform = entity.gameObject.transform;
 190
 8191        if (faceDirection)
 2192            entityTransform.forward = (endPosition - startPosition).normalized;
 193
 8194        entityTransform.localPosition = startPosition;
 8195        var tweener = entityTransform.DOLocalMove(endPosition, durationInSeconds).SetEase(ease).SetAutoKill(false);
 196
 8197        sbcInternalComponent.SetPosition(scene, entity, entityTransform.position);
 198
 8199        return tweener;
 200    }
 201}