diff --git a/CHANGELIST.md b/CHANGELIST.md
index 4ee1acee..72546337 100644
--- a/CHANGELIST.md
+++ b/CHANGELIST.md
@@ -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)
diff --git a/MPF.UI.Core/UserControls/LogOutput.xaml.cs b/MPF.UI.Core/UserControls/LogOutput.xaml.cs
index 80ea3d6c..79408a2f 100644
--- a/MPF.UI.Core/UserControls/LogOutput.xaml.cs
+++ b/MPF.UI.Core/UserControls/LogOutput.xaml.cs
@@ -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
{
///
- /// Read-only access to the current log view model
+ /// Read-only access to the current log output view model
///
- 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
+
+ ///
+ /// Enqueue text to the log
+ ///
+ /// Text to write to the log
+ public void Log(string text) => LogInternal(text, LogLevel.USER);
+
+ ///
+ /// Enqueue text with a newline to the log
+ ///
+ /// Text to write to the log
+ public void LogLn(string text) => Log(text + "\n");
+
+ ///
+ /// Enqueue error text to the log
+ ///
+ /// Text to write to the log
+ public void ErrorLog(string text) => LogInternal(text, LogLevel.ERROR);
+
+ ///
+ /// Enqueue error text with a newline to the log
+ ///
+ /// Text to write to the log
+ public void ErrorLogLn(string text) => ErrorLog(text + "\n");
+
+ ///
+ /// Enqueue secret text to the log
+ ///
+ /// Text to write to the log
+ public void SecretLog(string text) => LogInternal(text, LogLevel.SECRET);
+
+ ///
+ /// Enqueue secret text with a newline to the log
+ ///
+ /// Text to write to the log
+ public void SecretLogLn(string text) => SecretLog(text + "\n");
+
+ ///
+ /// Enqueue verbose text to the log
+ ///
+ /// Text to write to the log
+ public void VerboseLog(string text) => LogInternal(text, LogLevel.VERBOSE);
+
+ ///
+ /// Enqueue verbose text with a newline to the log
+ ///
+ /// Text to write to the log
+ public void VerboseLogLn(string text) => VerboseLog(text + "\n");
+
+ ///
+ /// Reset the progress bar state
+ ///
+ public void ResetProgressBar()
+ {
+ Dispatcher.Invoke(() =>
+ {
+ ProgressBar.Value = 0;
+ ProgressLabel.Text = string.Empty;
+ });
+ }
+
+ ///
+ /// Enqueue text to the log with formatting
+ ///
+ /// Text to write to the log
+ /// LogLevel for the log
+ 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
+
+ ///
+ /// Scroll the current view to the bottom
+ ///
+ 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
}
}
diff --git a/MPF.UI.Core/ViewModels/LogViewModel.cs b/MPF.UI.Core/ViewModels/LogOutputViewModel.cs
similarity index 51%
rename from MPF.UI.Core/ViewModels/LogViewModel.cs
rename to MPF.UI.Core/ViewModels/LogOutputViewModel.cs
index d0985fc9..13fb62f8 100644
--- a/MPF.UI.Core/ViewModels/LogViewModel.cs
+++ b/MPF.UI.Core/ViewModels/LogOutputViewModel.cs
@@ -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
+ ///
+ /// Document representing the text
+ ///
+ internal FlowDocument Document { get; private set; }
///
- /// Parent OptionsWindow object
+ /// Queue of items that need to be logged
///
- public LogOutput Parent { get; private set; }
-
- #endregion
-
- #region Private State Variables
+ internal ProcessingQueue LogQueue { get; private set; }
///
/// Paragraph backing the log
@@ -32,44 +29,44 @@ namespace MPF.UI.Core.ViewModels
///
private Run lastLine = null;
- ///
- /// Queue of items that need to be logged
- ///
- private readonly ProcessingQueue logQueue;
-
- #endregion
-
- ///
- /// Constructor
- ///
- 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(ProcessLogLine);
+ // Setup the processing queue
+ LogQueue = new ProcessingQueue(ProcessLogLine);
}
- #region Logging
+ ///
+ /// Clear all inlines of the paragraph
+ ///
+ public void ClearInlines() => _paragraph.Inlines.Clear();
+
+ ///
+ /// Save all inlines to console.log
+ ///
+ 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);
+ }
+ }
+ }
///
/// Log line wrapper
///
- private struct LogLine
+ internal struct LogLine
{
public readonly string Text;
public readonly LogLevel LogLevel;
@@ -110,89 +107,29 @@ namespace MPF.UI.Core.ViewModels
}
}
- ///
- /// Enqueue text to the log
- ///
- /// Text to write to the log
- public void Log(string text) => LogInternal(text, LogLevel.USER);
-
- ///
- /// Enqueue text with a newline to the log
- ///
- /// Text to write to the log
- public void LogLn(string text) => Log(text + "\n");
-
- ///
- /// Enqueue error text to the log
- ///
- /// Text to write to the log
- public void ErrorLog(string text) => LogInternal(text, LogLevel.ERROR);
-
- ///
- /// Enqueue error text with a newline to the log
- ///
- /// Text to write to the log
- public void ErrorLogLn(string text) => ErrorLog(text + "\n");
-
- ///
- /// Enqueue secret text to the log
- ///
- /// Text to write to the log
- public void SecretLog(string text) => LogInternal(text, LogLevel.SECRET);
-
- ///
- /// Enqueue secret text with a newline to the log
- ///
- /// Text to write to the log
- public void SecretLogLn(string text) => SecretLog(text + "\n");
-
- ///
- /// Enqueue verbose text to the log
- ///
- /// Text to write to the log
- public void VerboseLog(string text) => LogInternal(text, LogLevel.VERBOSE);
-
- ///
- /// Enqueue verbose text with a newline to the log
- ///
- /// Text to write to the log
- public void VerboseLogLn(string text) => VerboseLog(text + "\n");
-
- ///
- /// Reset the progress bar state
- ///
- public void ResetProgressBar()
- {
- Parent.Dispatcher.Invoke(() =>
- {
- Parent.ProgressBar.Value = 0;
- Parent.ProgressLabel.Text = string.Empty;
- });
- }
-
///
/// Enqueue text to the log with formatting
///
/// Text to write to the log
/// LogLevel for the log
- 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));
}
///
/// Process the log lines in the queue
///
/// LogLine item to process
- 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
/// LogLine value to append
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
/// LogLine value to append
private void ReplaceLastLine(LogLine logLine)
{
- Parent.Dispatcher.Invoke(() =>
+ Task.Run(() =>
{
lastLine.Text = logLine.Text;
lastLine.Foreground = logLine.GetForegroundColor();
});
}
-
- #endregion
-
- #region Helpers
-
- ///
- /// Scroll the current view to the bottom
- ///
- 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
}
}
diff --git a/MPF.UI.Core/ViewModels/MainViewModel.cs b/MPF.UI.Core/ViewModels/MainViewModel.cs
index 1421ad4a..38ed17a8 100644
--- a/MPF.UI.Core/ViewModels/MainViewModel.cs
+++ b/MPF.UI.Core/ViewModels/MainViewModel.cs
@@ -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
///
/// LogViewModel associated with the parent window
///
- public LogViewModel Logger => Parent.LogOutput.LogViewModel;
+ public LogOutput Logger => Parent.LogOutput;
///
/// Access to the current options