BizHawk/BizHawk.Client.EmuHawk/tools/TraceLogger.cs

337 lines
7.2 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.IEmulatorExtensions;
using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.WinFormExtensions;
namespace BizHawk.Client.EmuHawk
{
2014-12-22 19:01:21 +00:00
public partial class TraceLogger : Form, IToolFormAutoConfig
{
2014-12-15 03:19:23 +00:00
[RequiredService]
private ITraceable Tracer { get; set; }
2014-12-22 19:01:21 +00:00
[ConfigPersist]
private int MaxLines { get; set; }
private readonly List<string> _instructions = new List<string>();
private FileInfo _logFile;
2013-11-02 21:31:04 +00:00
public TraceLogger()
{
InitializeComponent();
TraceView.QueryItemText += TraceView_QueryItemText;
TraceView.VirtualMode = true;
2012-09-30 03:49:53 +00:00
Closing += (o, e) => SaveConfigSettings();
2014-12-22 19:01:21 +00:00
MaxLines = 10000;
}
public bool UpdateBefore
{
get { return false; }
}
public bool AskSaveChanges()
{
return true;
}
private void SaveConfigSettings()
{
Tracer.Enabled = false;
}
2012-09-30 03:09:41 +00:00
private void TraceView_QueryItemText(int index, int column, out string text)
{
2014-01-30 03:34:58 +00:00
text = index < _instructions.Count ? _instructions[index] : string.Empty;
}
private void TraceLogger_Load(object sender, EventArgs e)
{
ClearList();
LoggingEnabled.Checked = true;
Tracer.Enabled = true;
SetTracerBoxTitle();
}
public void UpdateValues()
{
TraceView.BlazingFast = !GlobalWin.MainForm.EmulatorPaused;
if (ToWindowRadio.Checked)
{
LogToWindow();
}
else
{
LogToFile();
}
}
public void FastUpdate()
{
2014-12-22 19:01:21 +00:00
// never skip instructions when tracelogging!
UpdateValues();
}
public void Restart()
{
ClearList();
LoggingEnabled.Checked = true;
Tracer.Enabled = true;
SetTracerBoxTitle();
}
private void ClearList()
{
_instructions.Clear();
TraceView.ItemCount = 0;
SetTracerBoxTitle();
}
private void LogToFile()
{
using (var sw = new StreamWriter(_logFile.FullName, true))
{
sw.Write(Tracer.TakeContents());
}
}
private void LogToWindow()
{
var instructions = Tracer.TakeContents().Split('\n');
2014-01-30 03:34:58 +00:00
if (!string.IsNullOrWhiteSpace(instructions[0]))
{
_instructions.AddRange(instructions);
}
2014-12-22 19:01:21 +00:00
if (_instructions.Count >= MaxLines)
{
2014-12-22 19:01:21 +00:00
_instructions.RemoveRange(0, _instructions.Count - MaxLines);
}
TraceView.ItemCount = _instructions.Count;
}
private void SetTracerBoxTitle()
{
if (Tracer.Enabled)
{
if (ToFileRadio.Checked)
{
TracerBox.Text = "Trace log - logging to file...";
}
else if (_instructions.Any())
{
TracerBox.Text = "Trace log - logging - " + _instructions.Count + " instructions";
}
else
{
TracerBox.Text = "Trace log - logging...";
}
}
else
{
if (_instructions.Any())
{
TracerBox.Text = "Trace log - " + _instructions.Count + " instructions";
}
else
{
TracerBox.Text = "Trace log";
}
}
}
private void CloseFile()
{
// TODO: save the remaining instructions in CoreComm
}
private FileInfo GetFileFromUser()
{
var sfd = new SaveFileDialog();
if (_logFile == null)
{
sfd.FileName = PathManager.FilesystemSafeName(Global.Game) + ".txt";
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null);
}
2014-01-30 03:34:58 +00:00
else if (!string.IsNullOrWhiteSpace(_logFile.FullName))
{
sfd.FileName = PathManager.FilesystemSafeName(Global.Game);
sfd.InitialDirectory = Path.GetDirectoryName(_logFile.FullName);
}
else
{
sfd.FileName = Path.GetFileNameWithoutExtension(_logFile.FullName);
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null);
}
sfd.Filter = "Text Files (*.txt)|*.txt|Log Files (*.log)|*.log|All Files|*.*";
sfd.RestoreDirectory = true;
var result = sfd.ShowHawkDialog();
if (result == DialogResult.OK)
{
return new FileInfo(sfd.FileName);
}
else
{
return null;
}
}
private void DumpListToDisk(FileSystemInfo file)
{
using (var sw = new StreamWriter(file.FullName))
{
foreach (var instruction in _instructions)
{
sw.WriteLine(instruction
.Replace("\r", string.Empty)
.Replace("\n", string.Empty));
}
}
}
#region Events
#region Menu Items
private void SaveLogMenuItem_Click(object sender, EventArgs e)
{
var file = GetFileFromUser();
if (file != null)
{
DumpListToDisk(file);
GlobalWin.OSD.AddMessage("Log dumped to " + file.FullName);
}
}
private void ExitMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void CopyMenuItem_Click(object sender, EventArgs e)
{
var indices = TraceView.SelectedIndices;
if (indices.Count > 0)
{
var blob = new StringBuilder();
foreach (int index in indices)
{
if (blob.Length != 0) blob.AppendLine();
blob.Append(_instructions[index]
.Replace("\r", string.Empty)
.Replace("\n", string.Empty) );
}
Clipboard.SetDataObject(blob.ToString());
}
}
2012-11-28 18:59:56 +00:00
private void SelectAllMenuItem_Click(object sender, EventArgs e)
{
for (var i = 0; i < _instructions.Count; i++)
{
TraceView.SelectItem(i, true);
}
}
private void MaxLinesMenuItem_Click(object sender, EventArgs e)
{
var prompt = new InputPrompt
{
StartLocation = this.ChildPointToScreen(TraceView),
TextInputType = InputPrompt.InputType.Unsigned,
Message = "Max lines to display in the window",
2014-12-22 19:01:21 +00:00
InitialValue = MaxLines.ToString()
};
var result = prompt.ShowHawkDialog();
if (result == DialogResult.OK)
{
var max = int.Parse(prompt.PromptText);
if (max > 0)
{
2014-12-22 19:01:21 +00:00
MaxLines = max;
}
}
}
#endregion
#region Dialog and ListView Events
private void LoggingEnabled_CheckedChanged(object sender, EventArgs e)
{
Tracer.Enabled = LoggingEnabled.Checked;
SetTracerBoxTitle();
}
private void ClearButton_Click(object sender, EventArgs e)
{
ClearList();
}
private void BrowseBox_Click(object sender, EventArgs e)
{
var file = GetFileFromUser();
if (file != null)
{
_logFile = file;
FileBox.Text = _logFile.FullName;
}
2012-11-28 18:59:56 +00:00
}
private void ToFileRadio_CheckedChanged(object sender, EventArgs e)
2012-11-28 18:59:56 +00:00
{
if (ToFileRadio.Checked)
{
FileBox.Visible = true;
BrowseBox.Visible = true;
var name = PathManager.FilesystemSafeName(Global.Game);
var filename = Path.Combine(PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null), name) + ".txt";
_logFile = new FileInfo(filename);
if (_logFile.Directory != null && !_logFile.Directory.Exists)
{
_logFile.Directory.Create();
}
if (_logFile.Exists)
{
_logFile.Delete();
}
using (_logFile.Create()) { }
FileBox.Text = _logFile.FullName;
}
else
{
CloseFile();
FileBox.Visible = false;
BrowseBox.Visible = false;
}
SetTracerBoxTitle();
2012-11-28 18:59:56 +00:00
}
#endregion
#endregion
}
}