Added method interrupt handling.

This commit is contained in:
That_One_Nerd 2023-04-01 08:27:30 -04:00
parent 5412b023a0
commit 1e5f0dba4e
2 changed files with 85 additions and 33 deletions

View File

@ -8,18 +8,18 @@ internal static partial class Winmm
public enum PlaySoundFlags : uint public enum PlaySoundFlags : uint
{ {
SND_SYNC = 0x00000000, Sync = 0x00000000,
SND_ASYNC = 0x00000001, Async = 0x00000001,
SND_NODEFAULT = 0x00000002, NoDefault = 0x00000002,
SND_MEMORY = 0x00000004, Memory = 0x00000004,
SND_LOOP = 0x00000008, Loop = 0x00000008,
SND_NOSTOP = 0x00000010, NoStop = 0x00000010,
SND_PURGE = 0x00000040, Purge = 0x00000040,
SND_APPLICATION = 0x00000080, Application = 0x00000080,
SND_NOWAIT = 0x00002000, NoWait = 0x00002000,
SND_ALIAS = 0x00010000, Alias = 0x00010000,
SND_FILENAME = 0x00020000, FileName = 0x00020000,
SND_RESOURCE = 0x00040000, Resource = 0x00040000,
SND_ALIAS_ID = 0x00100000, AliasId = 0x00100000,
} }
} }

View File

@ -1,10 +1,12 @@
namespace SrcMod.Shell; using System.ComponentModel;
namespace SrcMod.Shell;
public class Shell public class Shell
{ {
public const string Author = "That_One_Nerd"; public const string Author = "That_One_Nerd";
public const string Name = "SrcMod"; public const string Name = "SrcMod";
public const string Version = "Alpha 0.3.0"; public const string Version = "Alpha 0.3.1";
public readonly string? ShellDirectory; public readonly string? ShellDirectory;
@ -19,6 +21,8 @@ public class Shell
private bool lastCancel; private bool lastCancel;
private bool printedCancel; private bool printedCancel;
private BackgroundWorker? activeCommand;
public Shell() public Shell()
{ {
Console.CursorVisible = false; Console.CursorVisible = false;
@ -83,6 +87,7 @@ public class Shell
Write($"{Author}", ConsoleColor.DarkYellow); Write($"{Author}", ConsoleColor.DarkYellow);
lastCancel = false; lastCancel = false;
activeCommand = null;
Console.CancelKeyPress += HandleCancel; Console.CancelKeyPress += HandleCancel;
ActiveGame = null; ActiveGame = null;
@ -131,10 +136,7 @@ public class Shell
Console.CursorTop -= 3; Console.CursorTop -= 3;
Write("Press ^C again to exit the shell.", ConsoleColor.Red); Write("Press ^C again to exit the shell.", ConsoleColor.Red);
// Send a warning sound. PlayWarningSound();
Winmm.PlaySound("SystemAsterisk", nint.Zero,
(uint)(Winmm.PlaySoundFlags.SND_ALIAS | Winmm.PlaySoundFlags.SND_ASYNC));
printedCancel = true; printedCancel = true;
Console.CursorTop += 2; Console.CursorTop += 2;
@ -213,24 +215,41 @@ public class Shell
int start = module.NameIsPrefix ? 2 : 1; int start = module.NameIsPrefix ? 2 : 1;
string[] args = parts.GetRange(start, parts.Count - start).ToArray(); string[] args = parts.GetRange(start, parts.Count - start).ToArray();
void runCommand(object? sender, DoWorkEventArgs e)
{
#if RELEASE #if RELEASE
try try
{ {
#endif #endif
command.Invoke(args); command.Invoke(args);
#if RELEASE #if RELEASE
} }
catch (TargetInvocationException ex) catch (TargetInvocationException ex)
{ {
Write($"[ERROR] {ex.InnerException!.Message}", ConsoleColor.Red); Write($"[ERROR] {ex.InnerException!.Message}", ConsoleColor.Red);
if (LoadingBarEnabled) LoadingBarEnd(); if (LoadingBarEnabled) LoadingBarEnd();
} }
catch (Exception ex) catch (Exception ex)
{ {
Write($"[ERROR] {ex.Message}", ConsoleColor.Red); Write($"[ERROR] {ex.Message}", ConsoleColor.Red);
if (LoadingBarEnabled) LoadingBarEnd(); if (LoadingBarEnabled) LoadingBarEnd();
} }
#endif #endif
}
activeCommand = new();
activeCommand.DoWork += runCommand;
activeCommand.RunWorkerAsync();
activeCommand.WorkerSupportsCancellation = true;
while (activeCommand is not null && activeCommand.IsBusy) Thread.Yield();
if (activeCommand is not null)
{
activeCommand.Dispose();
activeCommand = null;
}
return; return;
} }
} }
@ -238,6 +257,17 @@ public class Shell
Write($"[ERROR] Could not find command \"{cmd}\".", ConsoleColor.Red); Write($"[ERROR] Could not find command \"{cmd}\".", ConsoleColor.Red);
} }
private static void PlayErrorSound()
{
Winmm.PlaySound("SystemHand", nint.Zero,
(uint)(Winmm.PlaySoundFlags.Alias | Winmm.PlaySoundFlags.Async));
}
private static void PlayWarningSound()
{
Winmm.PlaySound("SystemAsterisk", nint.Zero,
(uint)(Winmm.PlaySoundFlags.Alias | Winmm.PlaySoundFlags.Async));
}
public void ReloadDirectoryInfo() public void ReloadDirectoryInfo()
{ {
ActiveMod = Mod.ReadDirectory(WorkingDirectory); ActiveMod = Mod.ReadDirectory(WorkingDirectory);
@ -250,6 +280,28 @@ public class Shell
private void HandleCancel(object? sender, ConsoleCancelEventArgs args) private void HandleCancel(object? sender, ConsoleCancelEventArgs args)
{ {
if (activeCommand is not null && activeCommand.IsBusy)
{
if (activeCommand.WorkerSupportsCancellation)
{
// Kill the active command.
activeCommand.CancelAsync();
activeCommand.Dispose();
activeCommand = null;
}
else
{
// Command doesn't support cancellation.
// Warn the user.
PlayErrorSound();
}
lastCancel = false;
printedCancel = false;
args.Cancel = true;
return;
}
// Due to some funny multithreading issues, we want to make the warning label // Due to some funny multithreading issues, we want to make the warning label
// single-threaded on the shell. // single-threaded on the shell.
if (!lastCancel) if (!lastCancel)