diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-08-01 11:07:29 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-08-01 11:07:29 -0400 |
commit | 60b41195778af33fd609eab66d9ae3f1d1165e8f (patch) | |
tree | 7128b906d40e94c56c34ed6058f27bc31c31a08b /src/SMAPI/Framework/Monitor.cs | |
parent | b9bc1a6d17cafa0a97b46ffecda432cfc2f23b51 (diff) | |
parent | 52cf953f685c65b2b6814e375ec9a5ffa03c440a (diff) | |
download | SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.tar.gz SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.tar.bz2 SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.zip |
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI/Framework/Monitor.cs')
-rw-r--r-- | src/SMAPI/Framework/Monitor.cs | 116 |
1 files changed, 36 insertions, 80 deletions
diff --git a/src/SMAPI/Framework/Monitor.cs b/src/SMAPI/Framework/Monitor.cs index bf338386..2812a9cc 100644 --- a/src/SMAPI/Framework/Monitor.cs +++ b/src/SMAPI/Framework/Monitor.cs @@ -1,8 +1,8 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Threading; using StardewModdingAPI.Framework.Logging; +using StardewModdingAPI.Internal.ConsoleWriting; namespace StardewModdingAPI.Framework { @@ -15,8 +15,11 @@ namespace StardewModdingAPI.Framework /// <summary>The name of the module which logs messages using this instance.</summary> private readonly string Source; + /// <summary>Handles writing color-coded text to the console.</summary> + private readonly ColorfulConsoleWriter ConsoleWriter; + /// <summary>Manages access to the console output.</summary> - private readonly ConsoleInterceptionManager ConsoleManager; + private readonly ConsoleInterceptionManager ConsoleInterceptor; /// <summary>The log file to which to write messages.</summary> private readonly LogFileManager LogFile; @@ -24,9 +27,6 @@ namespace StardewModdingAPI.Framework /// <summary>The maximum length of the <see cref="LogLevel"/> values.</summary> private static readonly int MaxLevelLength = (from level in Enum.GetValues(typeof(LogLevel)).Cast<LogLevel>() select level.ToString().Length).Max(); - /// <summary>The console text color for each log level.</summary> - private static readonly IDictionary<LogLevel, ConsoleColor> Colors = Monitor.GetConsoleColorScheme(); - /// <summary>Propagates notification that SMAPI should exit.</summary> private readonly CancellationTokenSource ExitTokenSource; @@ -46,19 +46,17 @@ namespace StardewModdingAPI.Framework /// <summary>Whether to write anything to the console. This should be disabled if no console is available.</summary> internal bool WriteToConsole { get; set; } = true; - /// <summary>Whether to write anything to the log file. This should almost always be enabled.</summary> - internal bool WriteToFile { get; set; } = true; - /********* ** Public methods *********/ /// <summary>Construct an instance.</summary> /// <param name="source">The name of the module which logs messages using this instance.</param> - /// <param name="consoleManager">Manages access to the console output.</param> + /// <param name="consoleInterceptor">Intercepts access to the console output.</param> /// <param name="logFile">The log file to which to write messages.</param> /// <param name="exitTokenSource">Propagates notification that SMAPI should exit.</param> - public Monitor(string source, ConsoleInterceptionManager consoleManager, LogFileManager logFile, CancellationTokenSource exitTokenSource) + /// <param name="colorScheme">The console color scheme to use.</param> + public Monitor(string source, ConsoleInterceptionManager consoleInterceptor, LogFileManager logFile, CancellationTokenSource exitTokenSource, MonitorColorScheme colorScheme) { // validate if (string.IsNullOrWhiteSpace(source)) @@ -67,7 +65,8 @@ namespace StardewModdingAPI.Framework // initialise this.Source = source; this.LogFile = logFile ?? throw new ArgumentNullException(nameof(logFile), "The log file manager cannot be null."); - this.ConsoleManager = consoleManager; + this.ConsoleWriter = new ColorfulConsoleWriter(Constants.Platform, colorScheme); + this.ConsoleInterceptor = consoleInterceptor; this.ExitTokenSource = exitTokenSource; } @@ -76,7 +75,7 @@ namespace StardewModdingAPI.Framework /// <param name="level">The log severity level.</param> public void Log(string message, LogLevel level = LogLevel.Debug) { - this.LogImpl(this.Source, message, level, Monitor.Colors[level]); + this.LogImpl(this.Source, message, (ConsoleLogLevel)level); } /// <summary>Immediately exit the game without saving. This should only be invoked when an irrecoverable fatal error happens that risks save corruption or game-breaking bugs.</summary> @@ -91,9 +90,17 @@ namespace StardewModdingAPI.Framework internal void Newline() { if (this.WriteToConsole) - this.ConsoleManager.ExclusiveWriteWithoutInterception(Console.WriteLine); - if (this.WriteToFile) - this.LogFile.WriteLine(""); + this.ConsoleInterceptor.ExclusiveWriteWithoutInterception(Console.WriteLine); + this.LogFile.WriteLine(""); + } + + /// <summary>Log console input from the user.</summary> + /// <param name="input">The user input to log.</param> + internal void LogUserInput(string input) + { + // user input already appears in the console, so just need to write to file + string prefix = this.GenerateMessagePrefix(this.Source, (ConsoleLogLevel)LogLevel.Info); + this.LogFile.WriteLine($"{prefix} $>{input}"); } @@ -104,91 +111,40 @@ namespace StardewModdingAPI.Framework /// <param name="message">The message to log.</param> private void LogFatal(string message) { - this.LogImpl(this.Source, message, LogLevel.Error, ConsoleColor.White, background: ConsoleColor.Red); + this.LogImpl(this.Source, message, ConsoleLogLevel.Critical); } /// <summary>Write a message line to the log.</summary> /// <param name="source">The name of the mod logging the message.</param> /// <param name="message">The message to log.</param> /// <param name="level">The log level.</param> - /// <param name="color">The console foreground color.</param> - /// <param name="background">The console background color (or <c>null</c> to leave it as-is).</param> - private void LogImpl(string source, string message, LogLevel level, ConsoleColor color, ConsoleColor? background = null) + private void LogImpl(string source, string message, ConsoleLogLevel level) { // generate message - string levelStr = level.ToString().ToUpper().PadRight(Monitor.MaxLevelLength); - - string fullMessage = $"[{DateTime.Now:HH:mm:ss} {levelStr} {source}] {message}"; + string prefix = this.GenerateMessagePrefix(source, level); + string fullMessage = $"{prefix} {message}"; string consoleMessage = this.ShowFullStampInConsole ? fullMessage : $"[{source}] {message}"; // write to console - if (this.WriteToConsole && (this.ShowTraceInConsole || level != LogLevel.Trace)) + if (this.WriteToConsole && (this.ShowTraceInConsole || level != ConsoleLogLevel.Trace)) { - this.ConsoleManager.ExclusiveWriteWithoutInterception(() => + this.ConsoleInterceptor.ExclusiveWriteWithoutInterception(() => { - if (this.ConsoleManager.SupportsColor) - { - if (background.HasValue) - Console.BackgroundColor = background.Value; - Console.ForegroundColor = color; - Console.WriteLine(consoleMessage); - Console.ResetColor(); - } - else - Console.WriteLine(consoleMessage); + this.ConsoleWriter.WriteLine(consoleMessage, level); }); } // write to log file - if (this.WriteToFile) - this.LogFile.WriteLine(fullMessage); + this.LogFile.WriteLine(fullMessage); } - /// <summary>Get the color scheme to use for the current console.</summary> - private static IDictionary<LogLevel, ConsoleColor> GetConsoleColorScheme() - { - // scheme for dark console background - if (Monitor.IsDark(Console.BackgroundColor)) - { - return new Dictionary<LogLevel, ConsoleColor> - { - [LogLevel.Trace] = ConsoleColor.DarkGray, - [LogLevel.Debug] = ConsoleColor.DarkGray, - [LogLevel.Info] = ConsoleColor.White, - [LogLevel.Warn] = ConsoleColor.Yellow, - [LogLevel.Error] = ConsoleColor.Red, - [LogLevel.Alert] = ConsoleColor.Magenta - }; - } - - // scheme for light console background - return new Dictionary<LogLevel, ConsoleColor> - { - [LogLevel.Trace] = ConsoleColor.DarkGray, - [LogLevel.Debug] = ConsoleColor.DarkGray, - [LogLevel.Info] = ConsoleColor.Black, - [LogLevel.Warn] = ConsoleColor.DarkYellow, - [LogLevel.Error] = ConsoleColor.Red, - [LogLevel.Alert] = ConsoleColor.DarkMagenta - }; - } - - /// <summary>Get whether a console color should be considered dark, which is subjectively defined as 'white looks better than black on this text'.</summary> - /// <param name="color">The color to check.</param> - private static bool IsDark(ConsoleColor color) + /// <summary>Generate a message prefix for the current time.</summary> + /// <param name="source">The name of the mod logging the message.</param> + /// <param name="level">The log level.</param> + private string GenerateMessagePrefix(string source, ConsoleLogLevel level) { - switch (color) - { - case ConsoleColor.Black: - case ConsoleColor.Blue: - case ConsoleColor.DarkBlue: - case ConsoleColor.DarkRed: - case ConsoleColor.Red: - return true; - - default: - return false; - } + string levelStr = level.ToString().ToUpper().PadRight(Monitor.MaxLevelLength); + return $"[{DateTime.Now:HH:mm:ss} {levelStr} {source}]"; } } } |