-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathStatusText.cs
More file actions
152 lines (140 loc) · 5 KB
/
Copy pathStatusText.cs
File metadata and controls
152 lines (140 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using UnityEngine;
using UnityEngine.UI;
using System.Threading;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace GoogleMobileAds.Samples.Utility
{
/// <summary>
/// Text element which renders messages from Application.logMessageReceivedThreaded.
/// </summary>
[AddComponentMenu("GoogleMobileAds/Samples/Utility/StatusText")]
public class StatusText : Text
{
private SynchronizationContext _synchronizationContext;
private const int MAX_LINES = 25; // Adjust this value as needed
private List<string> _lines = new List<string>();
private Regex _colorTagRegex = new Regex(@"<color=[^>]+>|</color>");
private ScrollRect _scrollRect;
protected override void Awake()
{
base.Awake();
if (Application.isPlaying)
{
verticalOverflow = VerticalWrapMode.Overflow;
maskable = true;
supportRichText = true;
text = string.Empty;
_synchronizationContext = SynchronizationContext.Current;
_scrollRect = GetComponentInParent<ScrollRect>();
EnsureMask();
Application.logMessageReceivedThreaded += OnLogMessageReceivedThreaded;
}
}
private void EnsureMask()
{
GameObject target = null;
if (_scrollRect != null && _scrollRect.viewport != null)
{
target = _scrollRect.viewport.gameObject;
}
else if (transform.parent != null)
{
target = transform.parent.gameObject;
}
if (target != null &&
target.GetComponent<Mask>() == null &&
target.GetComponent<RectMask2D>() == null)
{
target.AddComponent<RectMask2D>();
}
}
protected override void OnDestroy()
{
base.OnDestroy();
Application.logMessageReceivedThreaded -= OnLogMessageReceivedThreaded;
}
private void OnLogMessageReceivedThreaded(string logString, string stackTrace, LogType type)
{
_synchronizationContext.Post((sender) =>
{
// Safeguard against race conditions from Unity disposed objects.
if (this == null || !Application.isPlaying)
{
return;
}
string color;
switch (type)
{
case LogType.Warning:
color = "yellow";
break;
case LogType.Error:
case LogType.Exception:
color = "red";
break;
default:
color = "white";
break;
}
string message = $"<color={color}>{logString}</color>\n\r";
_lines.Add(message);
if (_lines.Count > MAX_LINES)
{
RemoveOldestLines();
}
text = string.Join("", _lines);
if (_scrollRect == null)
{
_scrollRect = GetComponentInParent<ScrollRect>();
EnsureMask();
}
if (_scrollRect != null)
{
Canvas.ForceUpdateCanvases();
_scrollRect.verticalNormalizedPosition = 0f;
}
}, this);
}
/// <summary>
/// Removes the oldest lines from the list of lines to ensure that the list does not exceed
/// the maximum number of lines. It also ensures that the formatting of the lines is
/// preserved.
/// </summary>
private void RemoveOldestLines()
{
while (_lines.Count > MAX_LINES)
{
if (_colorTagRegex.IsMatch(_lines[0]) &&
!_colorTagRegex.IsMatch(_lines[_lines.Count - 1]))
{
// If the first line has a color tag, but the last line does not, we need to
// remove more lines.
int index = 0;
bool foundClosingTag = false;
for (int i = 0; i < _lines.Count; i++)
{
if (_lines[i].Contains("</color>"))
{
index = i;
foundClosingTag = true;
break;
}
}
if (foundClosingTag)
{
_lines.RemoveRange(0, index + 1);
}
else
{
_lines.Clear();
}
}
else
{
_lines.RemoveAt(0);
}
}
}
}
}