ConsoleLog.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using Ryujinx.Common.Logging;
  2. using System;
  3. using System.Collections.Concurrent;
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. namespace Ryujinx
  7. {
  8. static class ConsoleLog
  9. {
  10. private static Thread _messageThread;
  11. private static BlockingCollection<LogEventArgs> _messageQueue;
  12. private static Dictionary<LogLevel, ConsoleColor> _logColors;
  13. private static object _consoleLock;
  14. static ConsoleLog()
  15. {
  16. _logColors = new Dictionary<LogLevel, ConsoleColor>()
  17. {
  18. { LogLevel.Stub, ConsoleColor.DarkGray },
  19. { LogLevel.Info, ConsoleColor.White },
  20. { LogLevel.Warning, ConsoleColor.Yellow },
  21. { LogLevel.Error, ConsoleColor.Red }
  22. };
  23. _messageQueue = new BlockingCollection<LogEventArgs>(10);
  24. _consoleLock = new object();
  25. _messageThread = new Thread(() =>
  26. {
  27. while (!_messageQueue.IsCompleted)
  28. {
  29. try
  30. {
  31. PrintLog(_messageQueue.Take());
  32. }
  33. catch (InvalidOperationException)
  34. {
  35. // IOE means that Take() was called on a completed collection.
  36. // Some other thread can call CompleteAdding after we pass the
  37. // IsCompleted check but before we call Take.
  38. // We can simply catch the exception since the loop will break
  39. // on the next iteration.
  40. }
  41. }
  42. });
  43. _messageThread.IsBackground = true;
  44. _messageThread.Start();
  45. }
  46. private static void PrintLog(LogEventArgs e)
  47. {
  48. string formattedTime = e.Time.ToString(@"hh\:mm\:ss\.fff");
  49. string currentThread = Thread.CurrentThread.ManagedThreadId.ToString("d4");
  50. string message = formattedTime + " | " + currentThread + " " + e.Message;
  51. if (_logColors.TryGetValue(e.Level, out ConsoleColor color))
  52. {
  53. lock (_consoleLock)
  54. {
  55. Console.ForegroundColor = color;
  56. Console.WriteLine(message);
  57. Console.ResetColor();
  58. }
  59. }
  60. else
  61. {
  62. Console.WriteLine(message);
  63. }
  64. }
  65. public static void Log(object sender, LogEventArgs e)
  66. {
  67. if (!_messageQueue.IsAddingCompleted)
  68. {
  69. _messageQueue.Add(e);
  70. }
  71. }
  72. }
  73. }