|   |  | 1 |  | // Copyright (c) 2020-2024 dotBunny Inc. | 
|   |  | 2 |  | // dotBunny licenses this file to you under the BSL-1.0 license. | 
|   |  | 3 |  | // See the LICENSE file in the project root for more information. | 
|   |  | 4 |  |  | 
|   |  | 5 |  | #if UNITY_2022_2_OR_NEWER | 
|   |  | 6 |  |  | 
|   |  | 7 |  | using System; | 
|   |  | 8 |  | using GDX.Collections.Generic; | 
|   |  | 9 |  | using UnityEngine; | 
|   |  | 10 |  | using UnityEngine.UIElements; | 
|   |  | 11 |  |  | 
|   |  | 12 |  | namespace GDX.Developer | 
|   |  | 13 |  | { | 
|   |  | 14 |  |     public class IntegerChartWatch : WatchBase | 
|   |  | 15 |  |     { | 
|   |  | 16 |  |         CircularBuffer<float> m_ChartPercentage; | 
|   |  | 17 |  |  | 
|   |  | 18 |  |         int m_ValuesCount; | 
|   | 0 | 19 |  |         int m_MinimumValue = 0; | 
|   | 0 | 20 |  |         int m_MaximumValue = 100; | 
|   |  | 21 |  |         int m_Range; | 
|   | 0 | 22 |  |         int m_CachedValue = int.MinValue; | 
|   | 0 | 23 |  |         Sentiment m_CachedSentiment = Sentiment.Default; | 
|   |  | 24 |  |  | 
|   |  | 25 |  |         bool m_ShowLatestValue; | 
|   |  | 26 |  |         readonly Func<int> m_GetValue; | 
|   |  | 27 |  |         readonly Func<int, Sentiment> m_GetSentiment; | 
|   |  | 28 |  |  | 
|   |  | 29 |  |         readonly VisualElement m_ChartElement; | 
|   |  | 30 |  |         readonly Label m_ValueLabel; | 
|   |  | 31 |  |  | 
|   |  | 32 |  |         public IntegerChartWatch(string uniqueIdentifier, string displayName, Func<int> getValue, Func<int, Sentiment> g | 
|   |  | 33 |  |             int minimumValue = 0, int maximumValue = 100, int historicalCount = 250, bool showLatestValue = true, bool e | 
|   | 0 | 34 |  |             : base(uniqueIdentifier, displayName, enabled, minWidth, minHeight) | 
|   | 0 | 35 |  |         { | 
|   | 0 | 36 |  |             m_GetValue = getValue; | 
|   | 0 | 37 |  |             m_GetSentiment = getSentiment; | 
|   |  | 38 |  |  | 
|   | 0 | 39 |  |             m_ValuesCount = historicalCount; | 
|   | 0 | 40 |  |             m_ChartPercentage = new CircularBuffer<float>(historicalCount); | 
|   |  | 41 |  |  | 
|   | 0 | 42 |  |             m_MinimumValue = minimumValue; | 
|   | 0 | 43 |  |             m_MaximumValue = maximumValue; | 
|   | 0 | 44 |  |             m_Range = m_MaximumValue - m_MinimumValue; | 
|   |  | 45 |  |  | 
|   | 0 | 46 |  |             m_ShowLatestValue = showLatestValue; | 
|   |  | 47 |  |  | 
|   | 0 | 48 |  |             Label displayNameLabel = new Label() { text = displayName }; | 
|   | 0 | 49 |  |             displayNameLabel.AddToClassList("gdx-watch-left"); | 
|   |  | 50 |  |  | 
|   | 0 | 51 |  |             m_ChartElement = new VisualElement(); | 
|   | 0 | 52 |  |             m_ChartElement.AddToClassList("gdx-watch-right"); | 
|   | 0 | 53 |  |             m_ChartElement.AddToClassList("inner-box"); | 
|   |  | 54 |  |  | 
|   | 0 | 55 |  |             if (showLatestValue) | 
|   | 0 | 56 |  |             { | 
|   | 0 | 57 |  |                 m_ValueLabel = new Label(); | 
|   | 0 | 58 |  |                 m_ValueLabel.AddToClassList("default"); | 
|   | 0 | 59 |  |                 m_ChartElement.Add(m_ValueLabel); | 
|   | 0 | 60 |  |             } | 
|   |  | 61 |  |  | 
|   | 0 | 62 |  |             ContainerElement.Add(displayNameLabel); | 
|   | 0 | 63 |  |             ContainerElement.Add(m_ChartElement); | 
|   |  | 64 |  |  | 
|   | 0 | 65 |  |             m_ChartElement.generateVisualContent = GenerateVisualContent; | 
|   | 0 | 66 |  |         } | 
|   |  | 67 |  |  | 
|   |  | 68 |  |         void GenerateVisualContent(MeshGenerationContext ctx) | 
|   | 0 | 69 |  |         { | 
|   | 0 | 70 |  |             Painter2D paint2D = ctx.painter2D; | 
|   | 0 | 71 |  |             paint2D.strokeColor = m_CachedSentiment switch | 
|   |  | 72 |  |             { | 
|   | 0 | 73 |  |                 Sentiment.Good => Color.green, | 
|   | 0 | 74 |  |                 Sentiment.Warning => Color.yellow, | 
|   | 0 | 75 |  |                 Sentiment.Bad => Color.red, | 
|   | 0 | 76 |  |                 _ => Color.white | 
|   |  | 77 |  |             }; | 
|   | 0 | 78 |  |             paint2D.lineJoin = LineJoin.Round; | 
|   |  | 79 |  |  | 
|   | 0 | 80 |  |             float horizontalIncrement  = m_ChartElement.resolvedStyle.width / m_ValuesCount; | 
|   | 0 | 81 |  |             float verticalIncrement = m_ChartElement.resolvedStyle.height; | 
|   |  | 82 |  |  | 
|   | 0 | 83 |  |             paint2D.BeginPath(); | 
|   | 0 | 84 |  |             for (int i = 0; i < m_ValuesCount; i++) | 
|   | 0 | 85 |  |             { | 
|   | 0 | 86 |  |                 paint2D.LineTo(new Vector2(horizontalIncrement * i, | 
|   |  | 87 |  |                     m_ChartPercentage[i] * verticalIncrement)); | 
|   | 0 | 88 |  |             } | 
|   | 0 | 89 |  |             paint2D.Stroke(); | 
|   | 0 | 90 |  |         } | 
|   |  | 91 |  |  | 
|   |  | 92 |  |         public override void Poll() | 
|   | 0 | 93 |  |         { | 
|   | 0 | 94 |  |             int getValue = m_GetValue(); | 
|   | 0 | 95 |  |             if (m_GetSentiment != null) | 
|   | 0 | 96 |  |             { | 
|   | 0 | 97 |  |                 m_CachedSentiment = m_GetSentiment(getValue); | 
|   | 0 | 98 |  |             } | 
|   |  | 99 |  |  | 
|   | 0 | 100 |  |             if (getValue <= m_MinimumValue) | 
|   | 0 | 101 |  |             { | 
|   | 0 | 102 |  |                 m_ChartPercentage.Add(1f); | 
|   | 0 | 103 |  |             } | 
|   | 0 | 104 |  |             else if (getValue >= m_MaximumValue) | 
|   | 0 | 105 |  |             { | 
|   | 0 | 106 |  |                 m_ChartPercentage.Add(0f); | 
|   | 0 | 107 |  |             } | 
|   |  | 108 |  |             else | 
|   | 0 | 109 |  |             { | 
|   | 0 | 110 |  |                 m_ChartPercentage.Add((1f - (getValue - m_MinimumValue) / m_Range)); | 
|   | 0 | 111 |  |             } | 
|   |  | 112 |  |  | 
|   | 0 | 113 |  |             m_ChartElement.MarkDirtyRepaint(); | 
|   |  | 114 |  |  | 
|   |  | 115 |  |             // Latest Value Text | 
|   | 0 | 116 |  |             if (m_ShowLatestValue && getValue != m_CachedValue) | 
|   | 0 | 117 |  |             { | 
|   | 0 | 118 |  |                 m_ValueLabel.text = getValue.ToString(); | 
|   | 0 | 119 |  |                 if (m_GetSentiment != null) | 
|   | 0 | 120 |  |                 { | 
|   | 0 | 121 |  |                     Sentiment sentiment = m_GetSentiment(getValue); | 
|   | 0 | 122 |  |                     if (sentiment != m_CachedSentiment) | 
|   | 0 | 123 |  |                     { | 
|   |  | 124 |  |                         // Add colors | 
|   | 0 | 125 |  |                         AddSentimentToElement(m_ValueLabel, sentiment); | 
|   | 0 | 126 |  |                         m_CachedValue = getValue; | 
|   | 0 | 127 |  |                     } | 
|   | 0 | 128 |  |                 } | 
|   | 0 | 129 |  |             } | 
|   | 0 | 130 |  |         } | 
|   |  | 131 |  |     } | 
|   |  | 132 |  | } | 
|   |  | 133 |  |  | 
|   |  | 134 |  | #endif // UNITY_2022_2_OR_NEWER |