rjx-mirror/Ryujinx/Ui/ConsoleLog.cs
gdkchan 00579927e4
Better process implementation (#491)
* Initial implementation of KProcess

* Some improvements to the memory manager, implement back guest stack trace printing

* Better GetInfo implementation, improve checking in some places with information from process capabilities

* Allow the cpu to read/write from the correct memory locations for accesses crossing a page boundary

* Change long -> ulong for address/size on memory related methods to avoid unnecessary casts

* Attempt at implementing ldr:ro with new KProcess

* Allow BSS with size 0 on ldr:ro

* Add checking for memory block slab heap usage, return errors if full, exit gracefully

* Use KMemoryBlockSize const from KMemoryManager

* Allow all methods to read from non-contiguous locations

* Fix for TransactParcelAuto

* Address PR feedback, additionally fix some small issues related to the KIP loader and implement SVCs GetProcessId, GetProcessList, GetSystemInfo, CreatePort and ManageNamedPort

* Fix wrong check for source pages count from page list on MapPhysicalMemory

* Fix some issues with UnloadNro on ldr:ro
2018-11-28 20:18:09 -02:00

88 lines
No EOL
2.7 KiB
C#

using Ryujinx.Common.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
namespace Ryujinx
{
static class ConsoleLog
{
private static Thread _messageThread;
private static BlockingCollection<LogEventArgs> _messageQueue;
private static Dictionary<LogLevel, ConsoleColor> _logColors;
private static object _consoleLock;
static ConsoleLog()
{
_logColors = new Dictionary<LogLevel, ConsoleColor>()
{
{ LogLevel.Stub, ConsoleColor.DarkGray },
{ LogLevel.Info, ConsoleColor.White },
{ LogLevel.Warning, ConsoleColor.Yellow },
{ LogLevel.Error, ConsoleColor.Red }
};
_messageQueue = new BlockingCollection<LogEventArgs>(10);
_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();
}
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))
{
lock (_consoleLock)
{
Console.ForegroundColor = color;
Console.WriteLine(message);
Console.ResetColor();
}
}
else
{
Console.WriteLine(message);
}
}
public static void Log(object sender, LogEventArgs e)
{
if (!_messageQueue.IsAddingCompleted)
{
_messageQueue.Add(e);
}
}
}
}