diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-05-10 00:47:20 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-05-10 00:47:20 -0400 |
commit | 02c02a55eeeb744108d6a8335f6203a95ea20626 (patch) | |
tree | b6b7b6126c6077632114095d2bdeea937d47e4be /src/SMAPI | |
parent | 5a2755bfcc516345800a4e9b966a0aff435215b8 (diff) | |
download | SMAPI-02c02a55eeeb744108d6a8335f6203a95ea20626.tar.gz SMAPI-02c02a55eeeb744108d6a8335f6203a95ea20626.tar.bz2 SMAPI-02c02a55eeeb744108d6a8335f6203a95ea20626.zip |
generalise console color logic for reuse (#495)
Diffstat (limited to 'src/SMAPI')
-rw-r--r-- | src/SMAPI/Framework/Logging/ConsoleInterceptionManager.cs | 27 | ||||
-rw-r--r-- | src/SMAPI/Framework/Models/MonitorColorScheme.cs | 15 | ||||
-rw-r--r-- | src/SMAPI/Framework/Models/SConfig.cs | 2 | ||||
-rw-r--r-- | src/SMAPI/Framework/Monitor.cs | 111 | ||||
-rw-r--r-- | src/SMAPI/LogLevel.cs | 16 | ||||
-rw-r--r-- | src/SMAPI/StardewModdingAPI.csproj | 1 |
6 files changed, 29 insertions, 143 deletions
diff --git a/src/SMAPI/Framework/Logging/ConsoleInterceptionManager.cs b/src/SMAPI/Framework/Logging/ConsoleInterceptionManager.cs index b8f2c34e..c04bcd1a 100644 --- a/src/SMAPI/Framework/Logging/ConsoleInterceptionManager.cs +++ b/src/SMAPI/Framework/Logging/ConsoleInterceptionManager.cs @@ -15,9 +15,6 @@ namespace StardewModdingAPI.Framework.Logging /********* ** Accessors *********/ - /// <summary>Whether the current console supports color formatting.</summary> - public bool SupportsColor { get; } - /// <summary>The event raised when a message is written to the console directly.</summary> public event Action<string> OnMessageIntercepted; @@ -32,9 +29,6 @@ namespace StardewModdingAPI.Framework.Logging this.Output = new InterceptingTextWriter(Console.Out); this.Output.OnMessageIntercepted += line => this.OnMessageIntercepted?.Invoke(line); Console.SetOut(this.Output); - - // test color support - this.SupportsColor = this.TestColorSupport(); } /// <summary>Get an exclusive lock and write to the console output without interception.</summary> @@ -61,26 +55,5 @@ namespace StardewModdingAPI.Framework.Logging Console.SetOut(this.Output.Out); this.Output.Dispose(); } - - - /********* - ** private methods - *********/ - /// <summary>Test whether the current console supports color formatting.</summary> - private bool TestColorSupport() - { - try - { - this.ExclusiveWriteWithoutInterception(() => - { - Console.ForegroundColor = Console.ForegroundColor; - }); - return true; - } - catch (Exception) - { - return false; // Mono bug - } - } } } diff --git a/src/SMAPI/Framework/Models/MonitorColorScheme.cs b/src/SMAPI/Framework/Models/MonitorColorScheme.cs deleted file mode 100644 index d8289d08..00000000 --- a/src/SMAPI/Framework/Models/MonitorColorScheme.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace StardewModdingAPI.Framework.Models -{ - /// <summary>A monitor color scheme to use.</summary> - internal enum MonitorColorScheme - { - /// <summary>Choose a color scheme automatically.</summary> - AutoDetect, - - /// <summary>Use lighter text colors that look better on a black or dark background.</summary> - DarkBackground, - - /// <summary>Use darker text colors that look better on a white or light background.</summary> - LightBackground - } -} diff --git a/src/SMAPI/Framework/Models/SConfig.cs b/src/SMAPI/Framework/Models/SConfig.cs index b732921f..e201e966 100644 --- a/src/SMAPI/Framework/Models/SConfig.cs +++ b/src/SMAPI/Framework/Models/SConfig.cs @@ -1,3 +1,5 @@ +using StardewModdingAPI.Internal.ConsoleWriting; + namespace StardewModdingAPI.Framework.Models { /// <summary>The SMAPI configuration settings.</summary> diff --git a/src/SMAPI/Framework/Monitor.cs b/src/SMAPI/Framework/Monitor.cs index 8df2e59b..2812a9cc 100644 --- a/src/SMAPI/Framework/Monitor.cs +++ b/src/SMAPI/Framework/Monitor.cs @@ -1,10 +1,8 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Threading; using StardewModdingAPI.Framework.Logging; -using StardewModdingAPI.Framework.Models; -using StardewModdingAPI.Internal; +using StardewModdingAPI.Internal.ConsoleWriting; namespace StardewModdingAPI.Framework { @@ -17,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; @@ -26,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 readonly IDictionary<LogLevel, ConsoleColor> Colors; - /// <summary>Propagates notification that SMAPI should exit.</summary> private readonly CancellationTokenSource ExitTokenSource; @@ -54,21 +52,21 @@ namespace StardewModdingAPI.Framework *********/ /// <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> /// <param name="colorScheme">The console color scheme to use.</param> - public Monitor(string source, ConsoleInterceptionManager consoleManager, LogFileManager logFile, CancellationTokenSource exitTokenSource, MonitorColorScheme colorScheme) + public Monitor(string source, ConsoleInterceptionManager consoleInterceptor, LogFileManager logFile, CancellationTokenSource exitTokenSource, MonitorColorScheme colorScheme) { // validate if (string.IsNullOrWhiteSpace(source)) throw new ArgumentException("The log source cannot be empty."); // initialise - this.Colors = Monitor.GetConsoleColorScheme(colorScheme); 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; } @@ -77,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, this.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> @@ -92,7 +90,7 @@ namespace StardewModdingAPI.Framework internal void Newline() { if (this.WriteToConsole) - this.ConsoleManager.ExclusiveWriteWithoutInterception(Console.WriteLine); + this.ConsoleInterceptor.ExclusiveWriteWithoutInterception(Console.WriteLine); this.LogFile.WriteLine(""); } @@ -101,7 +99,7 @@ namespace StardewModdingAPI.Framework 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, LogLevel.Info); + string prefix = this.GenerateMessagePrefix(this.Source, (ConsoleLogLevel)LogLevel.Info); this.LogFile.WriteLine($"{prefix} $>{input}"); } @@ -113,16 +111,14 @@ 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 prefix = this.GenerateMessagePrefix(source, level); @@ -130,20 +126,11 @@ namespace StardewModdingAPI.Framework 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); }); } @@ -154,72 +141,10 @@ namespace StardewModdingAPI.Framework /// <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, LogLevel level) + private string GenerateMessagePrefix(string source, ConsoleLogLevel level) { string levelStr = level.ToString().ToUpper().PadRight(Monitor.MaxLevelLength); return $"[{DateTime.Now:HH:mm:ss} {levelStr} {source}]"; } - - /// <summary>Get the color scheme to use for the current console.</summary> - /// <param name="colorScheme">The console color scheme to use.</param> - private static IDictionary<LogLevel, ConsoleColor> GetConsoleColorScheme(MonitorColorScheme colorScheme) - { - // auto detect color scheme - if (colorScheme == MonitorColorScheme.AutoDetect) - { - if (Constants.Platform == Platform.Mac) - colorScheme = MonitorColorScheme.LightBackground; // MacOS doesn't provide console background color info, but it's usually white. - else - colorScheme = Monitor.IsDark(Console.BackgroundColor) ? MonitorColorScheme.DarkBackground : MonitorColorScheme.LightBackground; - } - - // get colors for scheme - switch (colorScheme) - { - case MonitorColorScheme.DarkBackground: - 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 - }; - - case MonitorColorScheme.LightBackground: - 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 - }; - - default: - throw new NotSupportedException($"Unknown color scheme '{colorScheme}'."); - } - } - - /// <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) - { - switch (color) - { - case ConsoleColor.Black: - case ConsoleColor.Blue: - case ConsoleColor.DarkBlue: - case ConsoleColor.DarkMagenta: // Powershell - case ConsoleColor.DarkRed: - case ConsoleColor.Red: - return true; - - default: - return false; - } - } } } diff --git a/src/SMAPI/LogLevel.cs b/src/SMAPI/LogLevel.cs index 89647876..7987f82a 100644 --- a/src/SMAPI/LogLevel.cs +++ b/src/SMAPI/LogLevel.cs @@ -1,24 +1,26 @@ +using StardewModdingAPI.Internal.ConsoleWriting; + namespace StardewModdingAPI { /// <summary>The log severity levels.</summary> public enum LogLevel { /// <summary>Tracing info intended for developers.</summary> - Trace, + Trace = ConsoleLogLevel.Trace, /// <summary>Troubleshooting info that may be relevant to the player.</summary> - Debug, + Debug = ConsoleLogLevel.Debug, /// <summary>Info relevant to the player. This should be used judiciously.</summary> - Info, + Info = ConsoleLogLevel.Info, /// <summary>An issue the player should be aware of. This should be used rarely.</summary> - Warn, + Warn = ConsoleLogLevel.Warn, /// <summary>A message indicating something went wrong.</summary> - Error, + Error = ConsoleLogLevel.Error, /// <summary>Important information to highlight for the player when player action is needed (e.g. new version available). This should be used rarely to avoid alert fatigue.</summary> - Alert + Alert = ConsoleLogLevel.Alert } -}
\ No newline at end of file +} diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index 320b97e7..01d5aaf1 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -125,7 +125,6 @@ <Compile Include="Framework\SContentManager.cs" /> <Compile Include="Framework\Exceptions\SAssemblyLoadFailedException.cs" /> <Compile Include="Framework\ModLoading\AssemblyLoadStatus.cs" /> - <Compile Include="Framework\Models\MonitorColorScheme.cs" /> <Compile Include="Framework\Reflection\InterfaceProxyBuilder.cs" /> <Compile Include="Framework\Reflection\InterfaceProxyFactory.cs" /> <Compile Include="Framework\RewriteFacades\SpriteBatchMethods.cs" /> |