static Logger() { // Register with Unity's logging system #if UNITY_5 UberDebug.UnityLog("Register"); Application.logMessageReceivedThreaded += UnityLogHandler; #else Application.RegisterLogCallback(UnityLogHandler); #endif StartTick = DateTime.Now.Ticks; UnityMessageRegex = new Regex(@"(.*)\((\d+).*\)"); }
/// <summary> /// Draws the main log panel /// </summary> public void DrawLogList(float height) { var oldColor = GUI.backgroundColor; float buttonY = 0; System.Text.RegularExpressions.Regex filterRegex = null; if (!String.IsNullOrEmpty(FilterRegex)) { filterRegex = new Regex(FilterRegex); } var collapseBadgeStyle = EditorStyles.miniButton; var logLineStyle = EntryStyleBackEven; // If we've been marked dirty, we need to recalculate the elements to be displayed if (Dirty) { LogListMaxWidth = 0; LogListLineHeight = 0; CollapseBadgeMaxWidth = 0; RenderLogs.Clear(); //When collapsed, count up the unique elements and use those to display if (Collapse) { var collapsedLines = new Dictionary <string, CountedLog>(); var collapsedLinesList = new List <CountedLog>(); foreach (var log in CurrentLogList) { if (ShouldShowLog(filterRegex, log)) { var matchString = log.Message + "!$" + log.Severity + "!$" + log.Channel; CountedLog countedLog; if (collapsedLines.TryGetValue(matchString, out countedLog)) { countedLog.Count++; } else { countedLog = new CountedLog(log, 1); collapsedLines.Add(matchString, countedLog); collapsedLinesList.Add(countedLog); } } } foreach (var countedLog in collapsedLinesList) { var content = GetLogLineGUIContent(countedLog.Log, ShowTimes); RenderLogs.Add(countedLog); var logLineSize = logLineStyle.CalcSize(content); LogListMaxWidth = Mathf.Max(LogListMaxWidth, logLineSize.x); LogListLineHeight = Mathf.Max(LogListLineHeight, logLineSize.y); var collapseBadgeContent = new GUIContent(countedLog.Count.ToString()); var collapseBadgeSize = collapseBadgeStyle.CalcSize(collapseBadgeContent); CollapseBadgeMaxWidth = Mathf.Max(CollapseBadgeMaxWidth, collapseBadgeSize.x); } } //If we're not collapsed, display everything in order else { foreach (var log in CurrentLogList) { if (ShouldShowLog(filterRegex, log)) { var content = GetLogLineGUIContent(log, ShowTimes); RenderLogs.Add(new CountedLog(log, 1)); var logLineSize = logLineStyle.CalcSize(content); LogListMaxWidth = Mathf.Max(LogListMaxWidth, logLineSize.x); LogListLineHeight = Mathf.Max(LogListLineHeight, logLineSize.y); } } } LogListMaxWidth += CollapseBadgeMaxWidth; } var scrollRect = new Rect(DrawPos, new Vector2(position.width, height)); float lineWidth = Mathf.Max(LogListMaxWidth, scrollRect.width); var contentRect = new Rect(0, 0, lineWidth, RenderLogs.Count * LogListLineHeight); Vector2 lastScrollPosition = LogListScrollPosition; LogListScrollPosition = GUI.BeginScrollView(scrollRect, LogListScrollPosition, contentRect); //If we're following the messages but the user has moved, cancel following if (ScrollFollowMessages) { if (lastScrollPosition.y - LogListScrollPosition.y > LogListLineHeight) { UberDebug.UnityLog(String.Format("{0} {1}", lastScrollPosition.y, LogListScrollPosition.y)); ScrollFollowMessages = false; } } float logLineX = CollapseBadgeMaxWidth; //Render all the elements int firstRenderLogIndex = (int)(LogListScrollPosition.y / LogListLineHeight); int lastRenderLogIndex = firstRenderLogIndex + (int)(height / LogListLineHeight); firstRenderLogIndex = Mathf.Clamp(firstRenderLogIndex, 0, RenderLogs.Count); lastRenderLogIndex = Mathf.Clamp(lastRenderLogIndex, 0, RenderLogs.Count); buttonY = firstRenderLogIndex * LogListLineHeight; for (int renderLogIndex = firstRenderLogIndex; renderLogIndex < lastRenderLogIndex; renderLogIndex++) { var countedLog = RenderLogs[renderLogIndex]; var log = countedLog.Log; logLineStyle = (renderLogIndex % 2 == 0) ? EntryStyleBackEven : EntryStyleBackOdd; if (renderLogIndex == SelectedRenderLog) { GUI.backgroundColor = new Color(0.5f, 0.5f, 1); } else { GUI.backgroundColor = Color.white; } //Make all messages single line var content = GetLogLineGUIContent(log, ShowTimes); var drawRect = new Rect(logLineX, buttonY, contentRect.width, LogListLineHeight); if (GUI.Button(drawRect, content, logLineStyle)) { //Select a message, or jump to source if it's double-clicked if (renderLogIndex == SelectedRenderLog) { if (EditorApplication.timeSinceStartup - LastMessageClickTime < DoubleClickInterval) { LastMessageClickTime = 0; // Attempt to display source code associated with messages. Search through all stackframes, // until we find a stackframe that can be displayed in source code view for (int frame = 0; frame < log.Callstack.Count; frame++) { if (JumpToSource(log.Callstack[frame])) { break; } } } else { LastMessageClickTime = EditorApplication.timeSinceStartup; } } else { SelectedRenderLog = renderLogIndex; SelectedCallstackFrame = -1; LastMessageClickTime = EditorApplication.timeSinceStartup; } //Always select the game object that is the source of this message var go = log.Source as GameObject; if (go != null) { Selection.activeGameObject = go; } } if (Collapse) { var collapseBadgeContent = new GUIContent(countedLog.Count.ToString()); var collapseBadgeSize = collapseBadgeStyle.CalcSize(collapseBadgeContent); var collapseBadgeRect = new Rect(0, buttonY, collapseBadgeSize.x, collapseBadgeSize.y); GUI.Button(collapseBadgeRect, collapseBadgeContent, collapseBadgeStyle); } buttonY += LogListLineHeight; } //If we're following the log, move to the end if (ScrollFollowMessages && RenderLogs.Count > 0) { LogListScrollPosition.y = ((RenderLogs.Count + 1) * LogListLineHeight) - scrollRect.height; } GUI.EndScrollView(); DrawPos.y += height; DrawPos.x = 0; GUI.backgroundColor = oldColor; }