Cleanup LogConsole

This commit is contained in:
adelikat 2019-12-21 12:41:13 -06:00
parent b65b9d64d7
commit 8ec8400ab2
3 changed files with 77 additions and 78 deletions

View File

@ -6,55 +6,39 @@ using System.Runtime.InteropServices;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
#pragma warning disable 162 // thanks! - http://sharp-developer.net/ru/CodeBank/WinForms/GuiConsole.aspx
// todo - quit using Console.WriteLine (well, we can leave it hooked up as a backstop)
//thanks! - http://sharp-developer.net/ru/CodeBank/WinForms/GuiConsole.aspx // use a different method instead, so we can collect unicode data
// also, collect log data independently of whether the log window is open
//todo - quit using Console.WriteLine (well, we can leave it hooked up as a backstop) // we also need to dice it into lines so that we can have a backlog policy
//use a different method instead, so we can collect unicode data
//also, collect log data independently of whether the log window is open
//we also need to dice it into lines so that we can have a backlog policy
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
static class LogConsole internal static class LogConsole
{ {
public static bool ConsoleVisible public static bool ConsoleVisible { get; private set; }
{
get;
private set;
}
static LogWindow window; private static LogWindow _window;
static LogStream logStream; private static LogStream _logStream;
static bool NeedToRelease; private static bool _needToRelease;
class LogStream : Stream private class LogStream : Stream
{ {
public override bool CanRead { get { return false; } } public override bool CanRead => false;
public override bool CanSeek { get { return false; } } public override bool CanSeek => false;
public override bool CanWrite { get { return true; } } public override bool CanWrite => true;
public override void Flush() public override void Flush()
{ {
//TODO - maybe this will help with decoding //TODO - maybe this will help with decoding
} }
public override long Length public override long Length => throw new NotImplementedException();
{
get { throw new NotImplementedException(); }
}
public override long Position public override long Position
{ {
get get => throw new NotImplementedException();
{ set => throw new NotImplementedException();
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
} }
public override int Read(byte[] buffer, int offset, int count) public override int Read(byte[] buffer, int offset, int count)
@ -77,18 +61,16 @@ namespace BizHawk.Client.EmuHawk
//TODO - buffer undecoded characters (this may be important) //TODO - buffer undecoded characters (this may be important)
//(use decoder = System.Text.Encoding.Unicode.GetDecoder()) //(use decoder = System.Text.Encoding.Unicode.GetDecoder())
string str = Encoding.ASCII.GetString(buffer, offset, count); string str = Encoding.ASCII.GetString(buffer, offset, count);
if (Emit != null) Emit?.Invoke(str);
Emit(str);
} }
public Action<string> Emit; public Action<string> Emit;
} }
static string SkipEverythingButProgramInCommandLine(string cmdLine) static string SkipEverythingButProgramInCommandLine(string cmdLine)
{ {
//skip past the program name. can anyone think of a better way to do this? // skip past the program name. can anyone think of a better way to do this?
//we could use CommandLineToArgvW (commented out below) but then we would just have to re-assemble and potentially re-quote it // we could use CommandLineToArgvW (commented out below) but then we would just have to re-assemble and potentially re-quote it
int childCmdLine = 0; int childCmdLine = 0;
int lastSlash = 0; int lastSlash = 0;
int lastGood = 0; int lastGood = 0;
@ -100,7 +82,10 @@ namespace BizHawk.Client.EmuHawk
if (childCmdLine == cmdLine.Length) break; if (childCmdLine == cmdLine.Length) break;
bool thisIsQuote = (cur == '\"'); bool thisIsQuote = (cur == '\"');
if (cur == '\\' || cur == '/') if (cur == '\\' || cur == '/')
{
lastSlash = childCmdLine; lastSlash = childCmdLine;
}
if (quote) if (quote)
{ {
if (thisIsQuote) if (thisIsQuote)
@ -121,10 +106,10 @@ namespace BizHawk.Client.EmuHawk
return $"{path} {remainder}"; return $"{path} {remainder}";
} }
static IntPtr oldOut, conOut; private static IntPtr oldOut, conOut;
static bool hasConsole; private static bool hasConsole;
static bool attachedConsole; private static bool attachedConsole;
static bool shouldRedirectStdout; private static bool shouldRedirectStdout;
public static void CreateConsole() public static void CreateConsole()
{ {
//(see desmume for the basis of some of this logic) //(see desmume for the basis of some of this logic)
@ -135,15 +120,15 @@ namespace BizHawk.Client.EmuHawk
if (oldOut == IntPtr.Zero) if (oldOut == IntPtr.Zero)
oldOut = Win32.GetStdHandle( -11 ); //STD_OUTPUT_HANDLE oldOut = Win32.GetStdHandle( -11 ); //STD_OUTPUT_HANDLE
Win32.FileType fileType = Win32.GetFileType(oldOut); var fileType = Win32.GetFileType(oldOut);
//stdout is already connected to something. keep using it and dont let the console interfere //stdout is already connected to something. keep using it and don't let the console interfere
shouldRedirectStdout = (fileType == Win32.FileType.FileTypeUnknown || fileType == Win32.FileType.FileTypePipe); shouldRedirectStdout = (fileType == Win32.FileType.FileTypeUnknown || fileType == Win32.FileType.FileTypePipe);
//attach to an existing console //attach to an existing console
attachedConsole = false; attachedConsole = false;
//ever since a recent KB, XP-based systems glitch out when attachconsole is called and theres no console to attach to. //ever since a recent KB, XP-based systems glitch out when attachconsole is called and there's no console to attach to.
if (Environment.OSVersion.Version.Major != 5) if (Environment.OSVersion.Version.Major != 5)
{ {
if (Win32.AttachConsole(-1)) if (Win32.AttachConsole(-1))
@ -164,10 +149,12 @@ namespace BizHawk.Client.EmuHawk
hasConsole = true; hasConsole = true;
} }
else else
{
System.Windows.Forms.MessageBox.Show($"Couldn't allocate win32 console: {Marshal.GetLastWin32Error()}"); System.Windows.Forms.MessageBox.Show($"Couldn't allocate win32 console: {Marshal.GetLastWin32Error()}");
}
} }
if(hasConsole) if (hasConsole)
{ {
IntPtr ptr = Win32.GetCommandLine(); IntPtr ptr = Win32.GetCommandLine();
string commandLine = Marshal.PtrToStringAuto(ptr); string commandLine = Marshal.PtrToStringAuto(ptr);
@ -195,10 +182,20 @@ namespace BizHawk.Client.EmuHawk
static void ReleaseConsole() static void ReleaseConsole()
{ {
if (!hasConsole) if (!hasConsole)
{
return; return;
}
if (shouldRedirectStdout)
{
Win32.CloseHandle(conOut);
}
if (!attachedConsole)
{
Win32.FreeConsole();
}
if(shouldRedirectStdout) Win32.CloseHandle(conOut);
if(!attachedConsole) Win32.FreeConsole();
Win32.SetStdHandle(-11, oldOut); Win32.SetStdHandle(-11, oldOut);
conOut = IntPtr.Zero; conOut = IntPtr.Zero;
@ -209,11 +206,15 @@ namespace BizHawk.Client.EmuHawk
/// pops the console in front of the main window (where it should probably go after booting up the game). /// pops the console in front of the main window (where it should probably go after booting up the game).
/// maybe this should be optional, or maybe we can somehow position the console sensibly. /// maybe this should be optional, or maybe we can somehow position the console sensibly.
/// sometimes it annoys me, but i really need it on top while debugging or else i will be annoyed. /// sometimes it annoys me, but i really need it on top while debugging or else i will be annoyed.
/// best of all would be to position it beneath the bizhawk main window somehow. /// best of all would be to position it beneath the BizHawk main window somehow.
/// </summary> /// </summary>
public static void PositionConsole() public static void PositionConsole()
{ {
if (ConsoleVisible == false) return; if (ConsoleVisible == false)
{
return;
}
if (Global.Config.WIN32_CONSOLE) if (Global.Config.WIN32_CONSOLE)
{ {
IntPtr x = Win32.GetConsoleWindow(); IntPtr x = Win32.GetConsoleWindow();
@ -228,61 +229,58 @@ namespace BizHawk.Client.EmuHawk
if (Global.Config.WIN32_CONSOLE) if (Global.Config.WIN32_CONSOLE)
{ {
NeedToRelease = true; _needToRelease = true;
CreateConsole(); CreateConsole();
//not sure whether we need to set a buffer size here
//var sout = new StreamWriter(Console.OpenStandardOutput(),Encoding.ASCII,1) { AutoFlush = true };
//var sout = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true };
//Console.SetOut(sout);
//Console.Title = "BizHawk Message Log";
//System.Runtime.InteropServices.SafeFi
//new Microsoft.Win32.SafeHandles.SafeFileHandle(
} }
else else
{ {
logStream = new LogStream(); _logStream = new LogStream();
Log.HACK_LOG_STREAM = logStream; Log.HACK_LOG_STREAM = _logStream;
var sout = new StreamWriter(logStream) { AutoFlush = true }; Console.SetOut(new StreamWriter(_logStream) { AutoFlush = true });
new StringBuilder(); //not using this right now _window = new LogWindow();
Console.SetOut(sout); _window.Show();
window = new LogWindow(); _logStream.Emit = str => { _window.Append(str); };
window.Show();
logStream.Emit = (str) => { window.Append(str); };
} }
} }
public static void HideConsole() public static void HideConsole()
{ {
if (ConsoleVisible == false) return; if (ConsoleVisible == false)
{
return;
}
Console.SetOut(TextWriter.Null); Console.SetOut(TextWriter.Null);
ConsoleVisible = false; ConsoleVisible = false;
if (NeedToRelease) if (_needToRelease)
{ {
ReleaseConsole(); ReleaseConsole();
NeedToRelease = false; _needToRelease = false;
} }
else else
{ {
logStream.Close(); _logStream.Close();
logStream = null; _logStream = null;
Log.HACK_LOG_STREAM = null; Log.HACK_LOG_STREAM = null;
window.Close(); _window.Close();
window = null; _window = null;
} }
} }
public static void notifyLogWindowClosing() public static void NotifyLogWindowClosing()
{ {
Console.SetOut(TextWriter.Null); Console.SetOut(TextWriter.Null);
ConsoleVisible = false; ConsoleVisible = false;
if(logStream != null) logStream.Close(); _logStream?.Close();
Log.HACK_LOG_STREAM = null; Log.HACK_LOG_STREAM = null;
} }
public static void SaveConfigSettings() public static void SaveConfigSettings()
{ {
if (window != null && window.IsHandleCreated) if (_window != null && _window.IsHandleCreated)
window.SaveConfigSettings(); {
_window.SaveConfigSettings();
}
} }
} }
} }

View File

@ -26,7 +26,7 @@ namespace BizHawk.Client.EmuHawk
{ {
Global.Config.ShowLogWindow = false; Global.Config.ShowLogWindow = false;
GlobalWin.MainForm.NotifyLogWindowClosing(); GlobalWin.MainForm.NotifyLogWindowClosing();
LogConsole.notifyLogWindowClosing(); LogConsole.NotifyLogWindowClosing();
SaveConfigSettings(); SaveConfigSettings();
}; };
ListView_ClientSizeChanged(null, null); ListView_ClientSizeChanged(null, null);

View File

@ -218,6 +218,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dega/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Dega/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=delaminated/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=delaminated/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dendy/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Dendy/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=desmume/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=desync/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=desync/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dipswitch/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Dipswitch/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Disasm/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Disasm/@EntryIndexedValue">True</s:Boolean>