180 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			180 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C#
		
	
	
	
| 
								 | 
							
								namespace SRDebugger.Services.Implementation
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    using SRF.Service;
							 | 
						|||
| 
								 | 
							
								    using UnityEngine;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    [Service(typeof (IConsoleService))]
							 | 
						|||
| 
								 | 
							
								    public class StandardConsoleService : IConsoleService
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        private readonly bool _collapseEnabled;
							 | 
						|||
| 
								 | 
							
								        private bool _hasCleared;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private readonly CircularBuffer<ConsoleEntry> _allConsoleEntries;
							 | 
						|||
| 
								 | 
							
								        private CircularBuffer<ConsoleEntry> _consoleEntries;
							 | 
						|||
| 
								 | 
							
								        private readonly object _threadLock = new object();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public StandardConsoleService()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            Application.logMessageReceivedThreaded += UnityLogCallback;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            SRServiceManager.RegisterService<IConsoleService>(this);
							 | 
						|||
| 
								 | 
							
								            _collapseEnabled = Settings.Instance.CollapseDuplicateLogEntries;
							 | 
						|||
| 
								 | 
							
								            _allConsoleEntries = new CircularBuffer<ConsoleEntry>(Settings.Instance.MaximumConsoleEntries);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public int ErrorCount { get; private set; }
							 | 
						|||
| 
								 | 
							
								        public int WarningCount { get; private set; }
							 | 
						|||
| 
								 | 
							
								        public int InfoCount { get; private set; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public event ConsoleUpdatedEventHandler Updated;
							 | 
						|||
| 
								 | 
							
								        public event ConsoleUpdatedEventHandler Error;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public IReadOnlyList<ConsoleEntry> Entries
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            get
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                if (!_hasCleared)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    return _allConsoleEntries;
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                return _consoleEntries;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public IReadOnlyList<ConsoleEntry> AllEntries
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            get { return _allConsoleEntries; }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public void Clear()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            lock (_threadLock)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                _hasCleared = true;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                if (_consoleEntries == null)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    _consoleEntries = new CircularBuffer<ConsoleEntry>(Settings.Instance.MaximumConsoleEntries);
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                else
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    _consoleEntries.Clear();
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                ErrorCount = WarningCount = InfoCount = 0;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            OnUpdated();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        protected void OnEntryAdded(ConsoleEntry entry)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (_hasCleared)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                // Decrement counters if adding this entry will push another
							 | 
						|||
| 
								 | 
							
								                // entry from the buffer.
							 | 
						|||
| 
								 | 
							
								                if (_consoleEntries.IsFull)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    AdjustCounter(_consoleEntries.Front().LogType, -1);
							 | 
						|||
| 
								 | 
							
								                    _consoleEntries.PopFront();
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                _consoleEntries.PushBack(entry);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            else
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                if (_allConsoleEntries.IsFull)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    AdjustCounter(_allConsoleEntries.Front().LogType, -1);
							 | 
						|||
| 
								 | 
							
								                    _allConsoleEntries.PopFront();
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            _allConsoleEntries.PushBack(entry);
							 | 
						|||
| 
								 | 
							
								            OnUpdated();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        protected void OnEntryDuplicated(ConsoleEntry entry)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            entry.Count++;
							 | 
						|||
| 
								 | 
							
								            OnUpdated();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            // If has cleared, add this entry again for the current list
							 | 
						|||
| 
								 | 
							
								            if (_hasCleared && _consoleEntries.Count == 0)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                OnEntryAdded(new ConsoleEntry(entry) {Count = 1});
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private void OnUpdated()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (Updated != null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                try
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    Updated(this);
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                catch {}
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private void UnityLogCallback(string condition, string stackTrace, LogType type)
							 | 
						|||
| 
								 | 
							
								        {                
							 | 
						|||
| 
								 | 
							
								            //if (condition.StartsWith("[SRConsole]"))
							 | 
						|||
| 
								 | 
							
								            //    return;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            lock (_threadLock)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                var prevMessage = _collapseEnabled && _allConsoleEntries.Count > 0
							 | 
						|||
| 
								 | 
							
								                    ? _allConsoleEntries[_allConsoleEntries.Count - 1]
							 | 
						|||
| 
								 | 
							
								                    : null;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                AdjustCounter(type, 1);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                if (prevMessage != null && prevMessage.LogType == type && prevMessage.Message == condition &&
							 | 
						|||
| 
								 | 
							
								                    prevMessage.StackTrace == stackTrace)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    OnEntryDuplicated(prevMessage);
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                else
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    var newEntry = new ConsoleEntry
							 | 
						|||
| 
								 | 
							
								                    {
							 | 
						|||
| 
								 | 
							
								                        LogType = type,
							 | 
						|||
| 
								 | 
							
								                        StackTrace = stackTrace,
							 | 
						|||
| 
								 | 
							
								                        Message = condition
							 | 
						|||
| 
								 | 
							
								                    };
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                    OnEntryAdded(newEntry);
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private void AdjustCounter(LogType type, int amount)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            switch (type)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                case LogType.Assert:
							 | 
						|||
| 
								 | 
							
								                case LogType.Error:
							 | 
						|||
| 
								 | 
							
								                case LogType.Exception:
							 | 
						|||
| 
								 | 
							
								                    ErrorCount += amount;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                    if (Error != null)
							 | 
						|||
| 
								 | 
							
								                    {
							 | 
						|||
| 
								 | 
							
								                        Error.Invoke(this);
							 | 
						|||
| 
								 | 
							
								                    }
							 | 
						|||
| 
								 | 
							
								                    break;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                case LogType.Warning:
							 | 
						|||
| 
								 | 
							
								                    WarningCount += amount;
							 | 
						|||
| 
								 | 
							
								                    break;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                case LogType.Log:
							 | 
						|||
| 
								 | 
							
								                    InfoCount += amount;
							 | 
						|||
| 
								 | 
							
								                    break;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |