< Summary

Class:ECSTextShapeComponentHandler
Assembly:DCL.ECSComponents.TextShape
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/TextShape/Handler/ECSTextShapeComponentHandler.cs
Covered lines:97
Uncovered lines:18
Coverable lines:115
Total lines:258
Line coverage:84.3% (97 of 115)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ECSTextShapeComponentHandler()0%110100%
ECSTextShapeComponentHandler(...)0%110100%
OnComponentCreated(...)0%220100%
OnComponentRemoved(...)0%220100%
OnComponentModelUpdated(...)0%4.014092.86%
RemoveModelFromPending(...)0%220100%
PrepareRectTransform(...)0%220100%
ApplyModelChanges(...)0%16.0413073.81%
GetAlignment(...)0%21.1213063.64%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/TextShape/Handler/ECSTextShapeComponentHandler.cs

#LineLine coverage
 1using System.Collections;
 2using System.Collections.Generic;
 3using DCL;
 4using DCL.Controllers;
 5using DCL.ECSComponents;
 6using DCL.ECSRuntime;
 7using DCL.Models;
 8using TMPro;
 9using UnityEngine;
 10
 11public class ECSTextShapeComponentHandler : IECSComponentHandler<PBTextShape>
 12{
 113    private static readonly int underlayColor = Shader.PropertyToID("_UnderlayColor");
 114    private static readonly int offsetX = Shader.PropertyToID("_UnderlayOffsetX");
 115    private static readonly int offsetY = Shader.PropertyToID("_UnderlayOffsetY");
 116    private static readonly int underlaySoftness = Shader.PropertyToID("_UnderlaySoftness");
 17
 18    private const string BOTTOM = "bottom";
 19    private const string TOP = "top";
 20    private const string LEFT = "left";
 21    private const string RIGHT = "right";
 22
 23    private const string COMPONENT_NAME = "TextShape";
 24
 25    internal GameObject textGameObject;
 26    internal TextMeshPro textComponent;
 27    internal RectTransform rectTransform;
 28    internal AssetPromise_Font promise;
 29
 30    private PBTextShape currentModel;
 31    private readonly DataStore_ECS7 dataStore;
 32    private readonly AssetPromiseKeeper_Font fontPromiseKeeper;
 33
 34    private string lastFontUsed;
 35
 3036    public ECSTextShapeComponentHandler(DataStore_ECS7 dataStoreEcs7, AssetPromiseKeeper_Font fontPromiseKeeper)
 37    {
 3038        dataStore = dataStoreEcs7;
 3039        this.fontPromiseKeeper = fontPromiseKeeper;
 3040    }
 41
 42    public void OnComponentCreated(IParcelScene scene, IDCLEntity entity)
 43    {
 3044        textGameObject = new GameObject(COMPONENT_NAME);
 3045        textGameObject.AddComponent<MeshRenderer>();
 3046        rectTransform = textGameObject.AddComponent<RectTransform>();
 3047        textComponent = textGameObject.AddComponent<TextMeshPro>();
 3048        textGameObject.transform.SetParent(entity.gameObject.transform,false);
 3049        dataStore.AddShapeReady(entity.entityId,textGameObject);
 3050        textComponent.text = string.Empty;
 51
 3052        if (entity.meshRootGameObject == null)
 3053            entity.meshesInfo.meshRootGameObject = textGameObject;
 3054    }
 55
 56    public void OnComponentRemoved(IParcelScene scene, IDCLEntity entity)
 57    {
 3258        RemoveModelFromPending(scene);
 3259        dataStore.RemoveShapeReady(entity.entityId);
 3260        if (promise != null)
 3261            fontPromiseKeeper.Forget(promise);
 3262        GameObject.Destroy(textGameObject);
 63
 3264        textGameObject = null;
 3265        textComponent = null;
 3266        rectTransform = null;
 3267        currentModel = null;
 3268    }
 69
 70    public void OnComponentModelUpdated(IParcelScene scene, IDCLEntity entity, PBTextShape model)
 71    {
 5872        if (model.Equals(currentModel))
 073            return;
 74
 5875        currentModel = model;
 76
 5877        PrepareRectTransform(model);
 78
 79        // If we use the same font than the last time, we just update the model, if not, we download it and apply the ch
 5880        if (lastFontUsed != null && lastFontUsed == model.Font)
 81        {
 2182            ApplyModelChanges(entity, model);
 2183        }
 84        else
 85        {
 3786            lastFontUsed = model.Font;
 3787            dataStore.AddPendingResource(scene.sceneData.id, model);
 3788            promise = new AssetPromise_Font(model.Font);
 3789            promise.OnSuccessEvent += assetFont =>
 90            {
 3091                textComponent.font = assetFont.font;
 3092                ApplyModelChanges(entity, model);
 93
 3094                RemoveModelFromPending(scene);
 3095            };
 3796            promise.OnFailEvent += ( mesh,  exception) =>
 97            {
 098                RemoveModelFromPending(scene);
 099            };
 100
 37101            fontPromiseKeeper.Keep(promise);
 102        }
 37103    }
 104
 105    private void RemoveModelFromPending(IParcelScene scene)
 106    {
 62107        if (currentModel != null)
 58108            dataStore.RemovePendingResource(scene.sceneData.id, currentModel);
 109
 62110        currentModel = null;
 62111    }
 112
 113    private void PrepareRectTransform(PBTextShape model)
 114    {
 58115        rectTransform.anchorMin = Vector2.zero;
 58116        rectTransform.anchorMax = Vector2.one;
 58117        rectTransform.offsetMin = Vector2.zero;
 58118        rectTransform.offsetMax = Vector2.zero;
 58119        rectTransform.sizeDelta = Vector2.zero;
 120
 121        // NOTE: previously width and height weren't working (setting sizeDelta before anchors and offset result in
 122        // sizeDelta being reset to 0,0)
 123        // to fix textWrapping and avoid backwards compatibility issues as result of the size being properly set (like t
 124        // we only set it if textWrapping is enabled.
 58125        if (model.TextWrapping)
 126        {
 4127            rectTransform.sizeDelta = new Vector2(model.GetWidth(), model.GetHeight());
 4128        }
 129        else
 130        {
 54131            rectTransform.sizeDelta = Vector2.zero;
 132        }
 54133    }
 134
 135    internal void ApplyModelChanges(IDCLEntity entity, PBTextShape model)
 136    {
 51137        textComponent.text = model.Text;
 138
 51139        if (model.TextColor != null)
 2140            textComponent.color = new UnityEngine.Color(model.TextColor.R, model.TextColor.G, model.TextColor.B, model.O
 141
 51142        textComponent.fontSize = model.GetFontSize();
 51143        textComponent.richText = true;
 51144        textComponent.overflowMode = TextOverflowModes.Overflow;
 51145        textComponent.enableAutoSizing = model.FontAutoSize;
 146
 51147        textComponent.margin =
 148            new Vector4
 149            (
 150                model.PaddingLeft,
 151                model.PaddingTop,
 152                model.PaddingRight,
 153                model.PaddingBottom
 154            );
 155
 51156        textComponent.alignment = GetAlignment(model.GetVTextAlign(), model.GetHTextAlign());
 51157        textComponent.lineSpacing = model.LineSpacing;
 158
 51159        if (model.LineCount != 0)
 160        {
 1161            textComponent.maxVisibleLines = Mathf.Max(model.LineCount, 1);
 1162        }
 163        else
 164        {
 50165            textComponent.maxVisibleLines = int.MaxValue;
 166        }
 167
 51168        textComponent.enableWordWrapping = model.TextWrapping && !textComponent.enableAutoSizing;
 169
 170        // Shadows
 51171        bool underlayKeywordEnabled = false;
 51172        if (!Mathf.Approximately(model.ShadowBlur,0))
 173        {
 0174            textComponent.fontSharedMaterial.EnableKeyword("UNDERLAY_ON");
 0175            textComponent.fontSharedMaterial.SetFloat(underlaySoftness, model.ShadowBlur);
 0176            underlayKeywordEnabled = true;
 177        }
 178
 51179        if (model.ShadowColor != null)
 180        {
 0181            if (!underlayKeywordEnabled)
 182            {
 0183                textComponent.fontSharedMaterial.EnableKeyword("UNDERLAY_ON");
 0184                underlayKeywordEnabled = true;
 185            }
 0186            var shadowColor = new UnityEngine.Color(model.ShadowColor.R, model.ShadowColor.G, model.ShadowColor.B, model
 0187            textComponent.fontSharedMaterial.SetColor(underlayColor, shadowColor);
 0188            textComponent.fontSharedMaterial.SetFloat(offsetX, model.ShadowOffsetX);
 0189            textComponent.fontSharedMaterial.SetFloat(offsetY, model.ShadowOffsetY);
 190        }
 191
 51192        if (!underlayKeywordEnabled && textComponent.fontSharedMaterial.IsKeywordEnabled("UNDERLAY_ON"))
 193        {
 0194            textComponent.fontSharedMaterial.DisableKeyword("UNDERLAY_ON");
 195        }
 196
 197        // Outline
 51198        if (model.OutlineWidth > 0f)
 199        {
 1200            textComponent.fontSharedMaterial.EnableKeyword("OUTLINE_ON");
 1201            textComponent.outlineWidth = model.OutlineWidth;
 1202            if (model.OutlineColor != null)
 203            {
 1204                var outlineColor  = new UnityEngine.Color(model.OutlineColor.R, model.OutlineColor.G, model.OutlineColor
 1205                textComponent.outlineColor = outlineColor;
 206            }
 1207        }
 50208        else if (textComponent.fontSharedMaterial.IsKeywordEnabled("OUTLINE_ON"))
 209        {
 1210            textComponent.fontSharedMaterial.DisableKeyword("OUTLINE_ON");
 211        }
 212
 51213        textGameObject.SetActive(model.GetVisible());
 51214        entity.OnShapeUpdated?.Invoke(entity);
 51215    }
 216
 217    internal TextAlignmentOptions GetAlignment(string vTextAlign, string hTextAlign)
 218    {
 55219        vTextAlign = vTextAlign.ToLower();
 55220        hTextAlign = hTextAlign.ToLower();
 221
 222        switch (vTextAlign)
 223        {
 224            case TOP:
 225                switch (hTextAlign)
 226                {
 227                    case LEFT:
 2228                        return TextAlignmentOptions.TopLeft;
 229                    case RIGHT:
 2230                        return TextAlignmentOptions.TopRight;
 231                    default:
 0232                        return TextAlignmentOptions.Top;
 233                }
 234
 235            case BOTTOM:
 236                switch (hTextAlign)
 237                {
 238                    case LEFT:
 2239                        return TextAlignmentOptions.BottomLeft;
 240                    case RIGHT:
 2241                        return TextAlignmentOptions.BottomRight;
 242                    default:
 0243                        return TextAlignmentOptions.Bottom;
 244                }
 245
 246            default: // center
 247                switch (hTextAlign)
 248                {
 249                    case LEFT:
 0250                        return TextAlignmentOptions.Left;
 251                    case RIGHT:
 0252                        return TextAlignmentOptions.Right;
 253                    default:
 47254                        return TextAlignmentOptions.Center;
 255                }
 256        }
 257    }
 258}