using System; using System.Linq; using BaseGames.Core.Events; using UnityEditor; using UnityEngine; namespace BaseGames.Editor { public sealed class EventBusMonitorWindow : EditorWindow { private string _filter = string.Empty; private bool _pauseCapture; private bool _autoScroll = true; private Vector2 _scroll; [MenuItem("BaseGames/Tools/Event Bus Monitor %#e")] public static void OpenWindow() { EventBusMonitorWindow window = GetWindow("Event Bus Monitor"); window.minSize = new Vector2(760f, 320f); } private void OnEnable() { EditorApplication.update += RepaintWhilePlaying; } private void OnDisable() { EditorApplication.update -= RepaintWhilePlaying; } private void OnGUI() { DrawToolbar(); DrawHeader(); DrawRows(); } private void DrawToolbar() { using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar)) { GUILayout.Label("Filter", GUILayout.Width(34f)); _filter = GUILayout.TextField(_filter, EditorStyles.toolbarTextField, GUILayout.MinWidth(180f)); GUILayout.Space(8f); _pauseCapture = GUILayout.Toggle(_pauseCapture, "Pause", EditorStyles.toolbarButton, GUILayout.Width(56f)); _autoScroll = GUILayout.Toggle(_autoScroll, "Auto Scroll", EditorStyles.toolbarButton, GUILayout.Width(82f)); if (GUILayout.Button("Clear", EditorStyles.toolbarButton, GUILayout.Width(48f))) EventBusMonitor.Clear(); GUILayout.FlexibleSpace(); GUILayout.Label(EditorApplication.isPlaying ? "Play Mode" : "Edit Mode", EditorStyles.miniLabel); } } private void DrawHeader() { using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("Time", EditorStyles.boldLabel, GUILayout.Width(80f)); GUILayout.Label("Frame", EditorStyles.boldLabel, GUILayout.Width(60f)); GUILayout.Label("Channel", EditorStyles.boldLabel, GUILayout.Width(220f)); GUILayout.Label("Payload", EditorStyles.boldLabel, GUILayout.ExpandWidth(true)); GUILayout.Label("Subs", EditorStyles.boldLabel, GUILayout.Width(48f)); } EditorGUILayout.LabelField(GUIContent.none, GUI.skin.horizontalSlider); } private void DrawRows() { var records = EventBusMonitor.Records; if (!string.IsNullOrWhiteSpace(_filter)) { records = records.Where(record => record.ChannelName.IndexOf(_filter, StringComparison.OrdinalIgnoreCase) >= 0 || record.Payload.IndexOf(_filter, StringComparison.OrdinalIgnoreCase) >= 0); } var displayRecords = records.ToArray(); _scroll = EditorGUILayout.BeginScrollView(_scroll); foreach (var record in displayRecords) DrawRow(record); EditorGUILayout.EndScrollView(); if (_autoScroll && Event.current.type == EventType.Repaint) _scroll.y = float.MaxValue; } private void DrawRow(EventBusMonitor.EventRecord record) { Color oldColor = GUI.color; if (record.ListenerCount == 0) GUI.color = new Color(1f, 0.65f, 0.65f); using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label(record.Timestamp.ToString("HH:mm:ss.fff"), GUILayout.Width(80f)); GUILayout.Label($"#{record.FrameCount}", GUILayout.Width(60f)); GUILayout.Label(record.ChannelName, GUILayout.Width(220f)); GUILayout.Label(record.Payload, GUILayout.ExpandWidth(true)); GUILayout.Label(record.ListenerCount.ToString(), GUILayout.Width(48f)); } GUI.color = oldColor; } private void RepaintWhilePlaying() { if (!_pauseCapture) Repaint(); } } }