using System; using System.Collections.Generic; using System.Threading.Tasks; using UnityEngine; namespace RudderSdk.Unity.Samples { sealed class SamplePage { const int MaxLogLines = 40; readonly string _title; readonly string _subtitle; readonly List _logLines = new List(); string _status = "Idle"; bool _error; string _output = string.Empty; bool _busy; Vector2 _outputScroll; Vector2 _logScroll; GUIStyle _titleStyle; GUIStyle _bodyStyle; GUIStyle _statusStyle; public SamplePage(string title, string subtitle) { _title = title; _subtitle = subtitle; } public void Draw(Action body) { EnsureStyles(); const float pad = 16f; GUILayout.BeginArea(new Rect(pad, pad, Screen.width - pad * 2f, Screen.height - pad * 2f)); GUILayout.Label(_title, _titleStyle); GUILayout.Label(_subtitle, _bodyStyle); _statusStyle.normal.textColor = _error ? new Color(1f, 0.45f, 0.4f) : Color.white; GUILayout.Label(_status, _statusStyle); GUILayout.Space(8f); var enabled = GUI.enabled; GUI.enabled = enabled && !_busy; body(); GUI.enabled = enabled; if (!string.IsNullOrEmpty(_output)) { GUILayout.Space(8f); _outputScroll = GUILayout.BeginScrollView(_outputScroll, GUILayout.MinHeight(120f)); GUILayout.Label(_output, _bodyStyle); GUILayout.EndScrollView(); } GUILayout.Space(8f); GUILayout.Label("Log", _titleStyle); _logScroll = GUILayout.BeginScrollView(_logScroll, GUILayout.MinHeight(100f)); if (_logLines.Count == 0) GUILayout.Label("(empty)", _bodyStyle); else GUILayout.Label(string.Join("\n", _logLines), _bodyStyle); GUILayout.EndScrollView(); GUILayout.EndArea(); } public bool Button(string text) { return GUILayout.Button(text, GUILayout.Height(28f), GUILayout.MaxWidth(280f)); } public void Label(string text) { GUILayout.Label(text, _bodyStyle); } public void SetStatus(string text, bool error = false) { _status = text; _error = error; } public void SetOutput(string text) { _output = text ?? string.Empty; } public void Log(string line) { _logLines.Insert(0, DateTime.Now.ToString("HH:mm:ss") + " " + line); if (_logLines.Count > MaxLogLines) _logLines.RemoveAt(_logLines.Count - 1); } public async void Run(MonoBehaviour host, Func action) { if (_busy) return; _busy = true; SetStatus("Working…"); try { await action(); } catch (Exception exception) { await Awaitable.MainThreadAsync(); if (host == null) return; SetStatus(exception.Message, true); Log(exception.Message); } finally { _busy = false; } } void EnsureStyles() { if (_titleStyle != null) return; _titleStyle = new GUIStyle(GUI.skin.label) { fontSize = 20, fontStyle = FontStyle.Bold, wordWrap = true }; _titleStyle.normal.textColor = Color.white; _bodyStyle = new GUIStyle(GUI.skin.label) { fontSize = 14, wordWrap = true }; _bodyStyle.normal.textColor = Color.white; _statusStyle = new GUIStyle(_bodyStyle); } } }