Split logging code a bit more

This commit is contained in:
Matt Nadareski
2023-10-07 01:59:28 -04:00
parent db544fd4b7
commit bb42e2db10
4 changed files with 165 additions and 149 deletions

View File

@@ -28,6 +28,7 @@
- Remove unnecessary include
- Move element items to Core
- Move LogLevel enumeration
- Split logging code a bit more
### 2.6.6 (2023-10-04)

View File

@@ -1,4 +1,7 @@
using System.Windows.Controls;
using System;
using System.Windows;
using System.Windows.Controls;
using MPF.Core.Data;
using MPF.UI.Core.ViewModels;
namespace MPF.UI.Core.UserControls
@@ -6,14 +9,130 @@ namespace MPF.UI.Core.UserControls
public partial class LogOutput : UserControl
{
/// <summary>
/// Read-only access to the current log view model
/// Read-only access to the current log output view model
/// </summary>
public LogViewModel LogViewModel => DataContext as LogViewModel;
public LogOutputViewModel LogOutputViewModel => DataContext as LogOutputViewModel;
public LogOutput()
{
InitializeComponent();
DataContext = new LogViewModel(this);
DataContext = new LogOutputViewModel();
// Add handlers
OutputViewer.SizeChanged += OutputViewerSizeChanged;
Output.TextChanged += OnTextChanged;
ClearButton.Click += OnClearButton;
SaveButton.Click += OnSaveButton;
// Update the internal state
Output.Document = LogOutputViewModel.Document;
}
#region Logging
/// <summary>
/// Enqueue text to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void Log(string text) => LogInternal(text, LogLevel.USER);
/// <summary>
/// Enqueue text with a newline to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void LogLn(string text) => Log(text + "\n");
/// <summary>
/// Enqueue error text to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void ErrorLog(string text) => LogInternal(text, LogLevel.ERROR);
/// <summary>
/// Enqueue error text with a newline to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void ErrorLogLn(string text) => ErrorLog(text + "\n");
/// <summary>
/// Enqueue secret text to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void SecretLog(string text) => LogInternal(text, LogLevel.SECRET);
/// <summary>
/// Enqueue secret text with a newline to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void SecretLogLn(string text) => SecretLog(text + "\n");
/// <summary>
/// Enqueue verbose text to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void VerboseLog(string text) => LogInternal(text, LogLevel.VERBOSE);
/// <summary>
/// Enqueue verbose text with a newline to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void VerboseLogLn(string text) => VerboseLog(text + "\n");
/// <summary>
/// Reset the progress bar state
/// </summary>
public void ResetProgressBar()
{
Dispatcher.Invoke(() =>
{
ProgressBar.Value = 0;
ProgressLabel.Text = string.Empty;
});
}
/// <summary>
/// Enqueue text to the log with formatting
/// </summary>
/// <param name="text">Text to write to the log</param>
/// <param name="logLevel">LogLevel for the log</param>
private void LogInternal(string text, LogLevel logLevel)
{
// Null text gets ignored
if (text == null)
return;
// Enqueue the text
LogOutputViewModel.LogQueue.Enqueue(new LogOutputViewModel.LogLine(text, logLevel));
}
#endregion
#region Helpers
/// <summary>
/// Scroll the current view to the bottom
/// </summary>
public void ScrollToBottom() => OutputViewer.ScrollToBottom();
#endregion
#region EventHandlers
private void OnClearButton(object sender, EventArgs e)
{
LogOutputViewModel.ClearInlines();
ResetProgressBar();
}
private void OnSaveButton(object sender, EventArgs e)
=> LogOutputViewModel.SaveInlines();
private void OnTextChanged(object sender, TextChangedEventArgs e)
=> ScrollToBottom();
private void OutputViewerSizeChanged(object sender, SizeChangedEventArgs e)
=> ScrollToBottom();
#endregion
}
}

View File

@@ -1,26 +1,23 @@
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Threading.Tasks;
using System.Windows.Documents;
using System.Windows.Media;
using MPF.Core.Data;
using MPF.UI.Core.UserControls;
namespace MPF.UI.Core.ViewModels
{
public class LogViewModel
public class LogOutputViewModel
{
#region Fields
/// <summary>
/// Document representing the text
/// </summary>
internal FlowDocument Document { get; private set; }
/// <summary>
/// Parent OptionsWindow object
/// Queue of items that need to be logged
/// </summary>
public LogOutput Parent { get; private set; }
#endregion
#region Private State Variables
internal ProcessingQueue<LogLine> LogQueue { get; private set; }
/// <summary>
/// Paragraph backing the log
@@ -32,44 +29,44 @@ namespace MPF.UI.Core.ViewModels
/// </summary>
private Run lastLine = null;
/// <summary>
/// Queue of items that need to be logged
/// </summary>
private readonly ProcessingQueue<LogLine> logQueue;
#endregion
/// <summary>
/// Constructor
/// </summary>
public LogViewModel(LogOutput parent)
public LogOutputViewModel()
{
Parent = parent;
// Add handlers
Parent.OutputViewer.SizeChanged += OutputViewerSizeChanged;
Parent.Output.TextChanged += OnTextChanged;
Parent.ClearButton.Click += OnClearButton;
Parent.SaveButton.Click += OnSaveButton;
// Update the internal state
var document = new FlowDocument()
Document = new FlowDocument()
{
Background = new SolidColorBrush(Color.FromArgb(0xFF, 0x20, 0x20, 0x20))
};
_paragraph = new Paragraph();
document.Blocks.Add(_paragraph);
Parent.Output.Document = document;
Document.Blocks.Add(_paragraph);
logQueue = new ProcessingQueue<LogLine>(ProcessLogLine);
// Setup the processing queue
LogQueue = new ProcessingQueue<LogLine>(ProcessLogLine);
}
#region Logging
/// <summary>
/// Clear all inlines of the paragraph
/// </summary>
public void ClearInlines() => _paragraph.Inlines.Clear();
/// <summary>
/// Save all inlines to console.log
/// </summary>
public void SaveInlines()
{
using (StreamWriter tw = new StreamWriter(File.OpenWrite("console.log")))
{
foreach (var inline in _paragraph.Inlines)
{
if (inline is Run run)
tw.Write(run.Text);
}
}
}
/// <summary>
/// Log line wrapper
/// </summary>
private struct LogLine
internal struct LogLine
{
public readonly string Text;
public readonly LogLevel LogLevel;
@@ -110,89 +107,29 @@ namespace MPF.UI.Core.ViewModels
}
}
/// <summary>
/// Enqueue text to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void Log(string text) => LogInternal(text, LogLevel.USER);
/// <summary>
/// Enqueue text with a newline to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void LogLn(string text) => Log(text + "\n");
/// <summary>
/// Enqueue error text to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void ErrorLog(string text) => LogInternal(text, LogLevel.ERROR);
/// <summary>
/// Enqueue error text with a newline to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void ErrorLogLn(string text) => ErrorLog(text + "\n");
/// <summary>
/// Enqueue secret text to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void SecretLog(string text) => LogInternal(text, LogLevel.SECRET);
/// <summary>
/// Enqueue secret text with a newline to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void SecretLogLn(string text) => SecretLog(text + "\n");
/// <summary>
/// Enqueue verbose text to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void VerboseLog(string text) => LogInternal(text, LogLevel.VERBOSE);
/// <summary>
/// Enqueue verbose text with a newline to the log
/// </summary>
/// <param name="text">Text to write to the log</param>
public void VerboseLogLn(string text) => VerboseLog(text + "\n");
/// <summary>
/// Reset the progress bar state
/// </summary>
public void ResetProgressBar()
{
Parent.Dispatcher.Invoke(() =>
{
Parent.ProgressBar.Value = 0;
Parent.ProgressLabel.Text = string.Empty;
});
}
/// <summary>
/// Enqueue text to the log with formatting
/// </summary>
/// <param name="text">Text to write to the log</param>
/// <param name="logLevel">LogLevel for the log</param>
private void LogInternal(string text, LogLevel logLevel)
internal void LogInternal(string text, LogLevel logLevel)
{
// Null text gets ignored
if (text == null)
return;
// Enqueue the text
logQueue.Enqueue(new LogLine(text, logLevel));
LogQueue.Enqueue(new LogLine(text, logLevel));
}
/// <summary>
/// Process the log lines in the queue
/// </summary>
/// <param name="nextLogLine">LogLine item to process</param>
private void ProcessLogLine(LogLine nextLogLine)
internal void ProcessLogLine(LogLine nextLogLine)
{
// Null text gets ignored
string nextText = Parent.Dispatcher.Invoke(() => nextLogLine.Text);
string nextText = nextLogLine.Text;
if (nextText == null)
return;
@@ -216,7 +153,7 @@ namespace MPF.UI.Core.ViewModels
/// <param name="logLine">LogLine value to append</param>
private void AppendToTextBox(LogLine logLine)
{
Parent.Dispatcher.Invoke(() =>
Task.Run(() =>
{
var run = logLine.GenerateRun();
_paragraph.Inlines.Add(run);
@@ -230,53 +167,11 @@ namespace MPF.UI.Core.ViewModels
/// <param name="logLine">LogLine value to append</param>
private void ReplaceLastLine(LogLine logLine)
{
Parent.Dispatcher.Invoke(() =>
Task.Run(() =>
{
lastLine.Text = logLine.Text;
lastLine.Foreground = logLine.GetForegroundColor();
});
}
#endregion
#region Helpers
/// <summary>
/// Scroll the current view to the bottom
/// </summary>
public void ScrollToBottom()
{
Parent.OutputViewer.ScrollToBottom();
}
#endregion
#region EventHandlers
private void OnClearButton(object sender, EventArgs e)
{
_paragraph.Inlines.Clear();
ResetProgressBar();
}
private void OnSaveButton(object sender, EventArgs e)
{
using (StreamWriter tw = new StreamWriter(File.OpenWrite("console.log")))
{
foreach (var inline in _paragraph.Inlines)
{
if (inline is Run run)
tw.Write(run.Text);
}
}
}
private void OnTextChanged(object sender, TextChangedEventArgs e) =>
ScrollToBottom();
private void OutputViewerSizeChanged(object sender, SizeChangedEventArgs e) =>
ScrollToBottom();
#endregion
}
}

View File

@@ -9,6 +9,7 @@ using MPF.Core;
using MPF.Core.Data;
using MPF.Core.Utilities;
using MPF.Core.UI.ComboBoxItems;
using MPF.UI.Core.UserControls;
using MPF.UI.Core.Windows;
using SabreTools.RedumpLib.Data;
using WPFCustomMessageBox;
@@ -28,7 +29,7 @@ namespace MPF.UI.Core.ViewModels
/// <summary>
/// LogViewModel associated with the parent window
/// </summary>
public LogViewModel Logger => Parent.LogOutput.LogViewModel;
public LogOutput Logger => Parent.LogOutput;
/// <summary>
/// Access to the current options