diff --git a/Ryujinx/Ui/ConsoleLog.cs b/Ryujinx/Ui/ConsoleLog.cs index 1a2899946b..6fb92e333f 100644 --- a/Ryujinx/Ui/ConsoleLog.cs +++ b/Ryujinx/Ui/ConsoleLog.cs @@ -1,5 +1,6 @@ using Ryujinx.HLE.Logging; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading; @@ -7,6 +8,10 @@ namespace Ryujinx { static class ConsoleLog { + private static Thread MessageThread; + + private static BlockingCollection MessageQueue; + private static Dictionary LogColors; private static object ConsoleLock; @@ -21,15 +26,39 @@ namespace Ryujinx { LogLevel.Error, ConsoleColor.Red } }; + MessageQueue = new BlockingCollection(); + ConsoleLock = new object(); + + MessageThread = new Thread(() => + { + while (!MessageQueue.IsCompleted) + { + try + { + PrintLog(MessageQueue.Take()); + } + catch (InvalidOperationException) + { + // IOE means that Take() was called on a completed collection. + // Some other thread can call CompleteAdding after we pass the + // IsCompleted check but before we call Take. + // We can simply catch the exception since the loop will break + // on the next iteration. + } + } + }); + + MessageThread.IsBackground = true; + MessageThread.Start(); } - public static void PrintLog(object sender, LogEventArgs e) + private static void PrintLog(LogEventArgs e) { string FormattedTime = e.Time.ToString(@"hh\:mm\:ss\.fff"); string CurrentThread = Thread.CurrentThread.ManagedThreadId.ToString("d4"); - + string Message = FormattedTime + " | " + CurrentThread + " " + e.Message; if (LogColors.TryGetValue(e.Level, out ConsoleColor Color)) @@ -47,5 +76,13 @@ namespace Ryujinx Console.WriteLine(Message); } } + + public static void Log(object sender, LogEventArgs e) + { + if (!MessageQueue.IsAddingCompleted) + { + MessageQueue.Add(e); + } + } } } \ No newline at end of file diff --git a/Ryujinx/Ui/Program.cs b/Ryujinx/Ui/Program.cs index 7acf73a552..fdbc59a5a8 100644 --- a/Ryujinx/Ui/Program.cs +++ b/Ryujinx/Ui/Program.cs @@ -22,7 +22,7 @@ namespace Ryujinx Config.Read(Device); - Device.Log.Updated += ConsoleLog.PrintLog; + Device.Log.Updated += ConsoleLog.Log; if (args.Length == 1) {