diff --git a/Terminal.Gui/ConsoleDrivers/AnsiEscapeSequence/AnsiEscapeSequenceRequestUtils.cs b/Terminal.Gui/ConsoleDrivers/AnsiEscapeSequence/AnsiEscapeSequenceRequestUtils.cs index fe13359e0..b68a08b27 100644 --- a/Terminal.Gui/ConsoleDrivers/AnsiEscapeSequence/AnsiEscapeSequenceRequestUtils.cs +++ b/Terminal.Gui/ConsoleDrivers/AnsiEscapeSequence/AnsiEscapeSequenceRequestUtils.cs @@ -183,7 +183,6 @@ public static class AnsiEscapeSequenceRequestUtils /// /// Decodes an ANSI escape sequence. /// - /// The which may contain a request. /// The which may change. /// The which may change. /// The array. @@ -198,7 +197,6 @@ public static class AnsiEscapeSequenceRequestUtils /// The object. /// The handler that will process the event. public static void DecodeEscSeq ( - AnsiEscapeSequenceRequests? escSeqRequests, ref ConsoleKeyInfo newConsoleKeyInfo, ref ConsoleKey key, ConsoleKeyInfo [] cki, @@ -346,9 +344,9 @@ public static class AnsiEscapeSequenceRequestUtils return; } - if (escSeqRequests is { } && escSeqRequests.HasResponse (terminator, out seqReqStatus)) + if (AnsiEscapeSequenceRequests.HasResponse (terminator, out seqReqStatus)) { - escSeqRequests.Remove (seqReqStatus); + AnsiEscapeSequenceRequests.Remove (seqReqStatus); return; } @@ -376,7 +374,7 @@ public static class AnsiEscapeSequenceRequestUtils else { // It's request response that wasn't handled by a valid request terminator - System.Diagnostics.Debug.Assert (escSeqRequests is null or { Statuses.Count: > 0 }); + System.Diagnostics.Debug.Assert (AnsiEscapeSequenceRequests.Statuses.Count > 0); InvalidRequestTerminator = ToString (cki); } diff --git a/Terminal.Gui/ConsoleDrivers/AnsiEscapeSequence/AnsiEscapeSequenceRequests.cs b/Terminal.Gui/ConsoleDrivers/AnsiEscapeSequence/AnsiEscapeSequenceRequests.cs index e6fffcfc3..62c0908fb 100644 --- a/Terminal.Gui/ConsoleDrivers/AnsiEscapeSequence/AnsiEscapeSequenceRequests.cs +++ b/Terminal.Gui/ConsoleDrivers/AnsiEscapeSequence/AnsiEscapeSequenceRequests.cs @@ -4,35 +4,36 @@ using System.Collections.Concurrent; namespace Terminal.Gui; -// TODO: This class is a singleton. It should use the singleton pattern. /// /// Manages ANSI Escape Sequence requests and responses. The list of /// contains the /// status of the request. Each request is identified by the terminator (e.g. ESC[8t ... t is the terminator). /// -public class AnsiEscapeSequenceRequests +public static class AnsiEscapeSequenceRequests { /// /// Adds a new request for the ANSI Escape Sequence defined by . Adds a /// instance to list. /// /// The object. - /// The driver in use. - public void Add (AnsiEscapeSequenceRequest ansiRequest, ConsoleDriver? driver = null) + public static void Add (AnsiEscapeSequenceRequest ansiRequest) + { + lock (ansiRequest._responseLock) + { + Statuses.Enqueue (new (ansiRequest)); + } + + System.Diagnostics.Debug.Assert (Statuses.Count > 0); + } + + /// + /// Clear the property. + /// + public static void Clear () { lock (Statuses) { - Statuses.Enqueue (new (ansiRequest)); - - if (driver is null) - { - Console.Out.Write (ansiRequest.Request); - Console.Out.Flush (); - } - else - { - driver.WriteRaw (ansiRequest.Request); - } + Statuses.Clear (); } } @@ -43,22 +44,13 @@ public class AnsiEscapeSequenceRequests /// /// /// if exist, otherwise. - public bool HasResponse (string terminator, out AnsiEscapeSequenceRequestStatus? seqReqStatus) + public static bool HasResponse (string terminator, out AnsiEscapeSequenceRequestStatus? seqReqStatus) { lock (Statuses) { Statuses.TryPeek (out seqReqStatus); - bool result = seqReqStatus?.AnsiRequest.Terminator == terminator; - - if (result) - { - return true; - } - - seqReqStatus = null; - - return false; + return seqReqStatus?.AnsiRequest.Terminator == terminator; } } @@ -70,7 +62,7 @@ public class AnsiEscapeSequenceRequests /// . /// /// The object. - public void Remove (AnsiEscapeSequenceRequestStatus? seqReqStatus) + public static void Remove (AnsiEscapeSequenceRequestStatus? seqReqStatus) { lock (Statuses) { @@ -84,5 +76,5 @@ public class AnsiEscapeSequenceRequests } /// Gets the list. - public ConcurrentQueue Statuses { get; } = new (); + public static ConcurrentQueue Statuses { get; } = new (); } diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 8b4a7c215..02c239733 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -806,7 +806,9 @@ internal class CursesDriver : ConsoleDriver _waitAnsiResponse.Set (); }; - _mainLoopDriver.EscSeqRequests.Add (ansiRequest, this); + AnsiEscapeSequenceRequests.Add (ansiRequest); + + WriteRaw (ansiRequest.Request); _mainLoopDriver._forceRead = true; } @@ -827,15 +829,15 @@ internal class CursesDriver : ConsoleDriver { _mainLoopDriver._forceRead = false; - if (_mainLoopDriver.EscSeqRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? request)) + if (AnsiEscapeSequenceRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? request)) { - if (_mainLoopDriver.EscSeqRequests.Statuses.Count > 0 + if (AnsiEscapeSequenceRequests.Statuses.Count > 0 && string.IsNullOrEmpty (request.AnsiRequest.AnsiEscapeSequenceResponse?.Response)) { lock (request.AnsiRequest._responseLock) { // Bad request or no response at all - _mainLoopDriver.EscSeqRequests.Statuses.TryDequeue (out _); + AnsiEscapeSequenceRequests.Statuses.TryDequeue (out _); } } } @@ -848,7 +850,6 @@ internal class CursesDriver : ConsoleDriver /// internal override void WriteRaw (string ansi) { _mainLoopDriver?.WriteRaw (ansi); } - } // TODO: One type per file - move to another file diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs index 203f67770..e9cc52166 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs @@ -1,3 +1,4 @@ +#nullable enable // // mainloop.cs: Linux/Curses MainLoop implementation. // @@ -12,7 +13,7 @@ namespace Terminal.Gui; /// In addition to the general functions of the MainLoop, the Unix version can watch file descriptors using the /// AddWatch methods. /// -internal class UnixMainLoop : IMainLoopDriver +internal class UnixMainLoop (ConsoleDriver consoleDriver) : IMainLoopDriver { /// Condition on which to wake up from file descriptor activity. These match the Linux/BSD poll definitions. [Flags] @@ -37,9 +38,9 @@ internal class UnixMainLoop : IMainLoopDriver PollNval = 32 } - private readonly CursesDriver _cursesDriver; - private MainLoop _mainLoop; - private Pollfd [] _pollMap; + private readonly CursesDriver _cursesDriver = (CursesDriver)consoleDriver ?? throw new ArgumentNullException (nameof (consoleDriver)); + private MainLoop? _mainLoop; + private Pollfd []? _pollMap; private readonly ConcurrentQueue _pollDataQueue = new (); private readonly ManualResetEventSlim _eventReady = new (false); internal readonly ManualResetEventSlim _waitForInput = new (false); @@ -47,13 +48,6 @@ internal class UnixMainLoop : IMainLoopDriver private readonly CancellationTokenSource _eventReadyTokenSource = new (); private readonly CancellationTokenSource _inputHandlerTokenSource = new (); - public UnixMainLoop (ConsoleDriver consoleDriver = null) - { - _cursesDriver = (CursesDriver)consoleDriver ?? throw new ArgumentNullException (nameof (consoleDriver)); - } - - public AnsiEscapeSequenceRequests EscSeqRequests { get; } = new (); - void IMainLoopDriver.Wakeup () { _eventReady.Set (); } void IMainLoopDriver.Setup (MainLoop mainLoop) @@ -110,7 +104,7 @@ internal class UnixMainLoop : IMainLoopDriver return GetTIOCGWINSZValueInternal (); } - private void EscSeqUtils_ContinuousButtonPressed (object sender, MouseEventArgs e) + private void EscSeqUtils_ContinuousButtonPressed (object? sender, MouseEventArgs e) { _pollDataQueue!.Enqueue (EnqueueMouseEvent (e.Flags, e.Position)); } @@ -238,15 +232,15 @@ internal class UnixMainLoop : IMainLoopDriver break; } - if (AnsiEscapeSequenceRequestUtils.IncompleteCkInfos is null && EscSeqRequests is { Statuses.Count: > 0 }) + if (AnsiEscapeSequenceRequestUtils.IncompleteCkInfos is null && AnsiEscapeSequenceRequests.Statuses.Count > 0) { if (_retries > 1) { - if (EscSeqRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus seqReqStatus) && seqReqStatus.AnsiRequest.AnsiEscapeSequenceResponse is { } && string.IsNullOrEmpty (seqReqStatus.AnsiRequest.AnsiEscapeSequenceResponse.Response)) + if (AnsiEscapeSequenceRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? seqReqStatus) && seqReqStatus.AnsiRequest.AnsiEscapeSequenceResponse is { } && string.IsNullOrEmpty (seqReqStatus.AnsiRequest.AnsiEscapeSequenceResponse.Response)) { lock (seqReqStatus!.AnsiRequest._responseLock) { - EscSeqRequests.Statuses.TryDequeue (out _); + AnsiEscapeSequenceRequests.Statuses.TryDequeue (out _); seqReqStatus.AnsiRequest.RaiseResponseFromInput (null); } @@ -299,21 +293,20 @@ internal class UnixMainLoop : IMainLoopDriver ConsoleKeyInfo newConsoleKeyInfo = default; AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - EscSeqRequests, - ref newConsoleKeyInfo, - ref key, - cki, - ref mod, - out string c1Control, - out string code, - out string [] values, - out string terminating, - out bool isMouse, - out List mouseFlags, - out Point pos, - out AnsiEscapeSequenceRequestStatus seqReqStatus, - AnsiEscapeSequenceRequestUtils.ProcessMouseEvent - ); + ref newConsoleKeyInfo, + ref key, + cki, + ref mod, + out string c1Control, + out string code, + out string [] values, + out string terminating, + out bool isMouse, + out List mouseFlags, + out Point pos, + out AnsiEscapeSequenceRequestStatus seqReqStatus, + AnsiEscapeSequenceRequestUtils.ProcessMouseEvent + ); if (isMouse) { @@ -339,7 +332,7 @@ internal class UnixMainLoop : IMainLoopDriver if (!string.IsNullOrEmpty (AnsiEscapeSequenceRequestUtils.InvalidRequestTerminator)) { - if (EscSeqRequests.Statuses.TryDequeue (out AnsiEscapeSequenceRequestStatus result)) + if (AnsiEscapeSequenceRequests.Statuses.TryDequeue (out AnsiEscapeSequenceRequestStatus? result)) { lock (result.AnsiRequest._responseLock) { diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver/NetDriver.cs index 607028811..81f9f57e4 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver/NetDriver.cs @@ -752,9 +752,9 @@ internal class NetDriver : ConsoleDriver _waitAnsiResponse.Set (); }; - _mainLoopDriver._netEvents!.EscSeqRequests.Add (ansiRequest); + AnsiEscapeSequenceRequests.Add (ansiRequest); - _mainLoopDriver._netEvents._forceRead = true; + _mainLoopDriver._netEvents!._forceRead = true; } if (!_ansiResponseTokenSource.IsCancellationRequested) @@ -763,6 +763,8 @@ internal class NetDriver : ConsoleDriver { _mainLoopDriver._waitForProbe.Set (); _mainLoopDriver._netEvents._waitForStart.Set (); + + WriteRaw (ansiRequest.Request); } _waitAnsiResponse.Wait (_ansiResponseTokenSource.Token); @@ -777,15 +779,15 @@ internal class NetDriver : ConsoleDriver { _mainLoopDriver._netEvents._forceRead = false; - if (_mainLoopDriver._netEvents.EscSeqRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? request)) + if (AnsiEscapeSequenceRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? request)) { - if (_mainLoopDriver._netEvents.EscSeqRequests.Statuses.Count > 0 + if (AnsiEscapeSequenceRequests.Statuses.Count > 0 && string.IsNullOrEmpty (request.AnsiRequest.AnsiEscapeSequenceResponse?.Response)) { lock (request.AnsiRequest._responseLock) { // Bad request or no response at all - _mainLoopDriver._netEvents.EscSeqRequests.Statuses.TryDequeue (out _); + AnsiEscapeSequenceRequests.Statuses.TryDequeue (out _); } } } @@ -797,7 +799,11 @@ internal class NetDriver : ConsoleDriver } /// - internal override void WriteRaw (string ansi) { throw new NotImplementedException (); } + internal override void WriteRaw (string ansi) + { + Console.Out.Write (ansi); + Console.Out.Flush (); + } private volatile bool _winSizeChanging; diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver/NetEvents.cs b/Terminal.Gui/ConsoleDrivers/NetDriver/NetEvents.cs index 46f0e3a13..decbc218c 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver/NetEvents.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver/NetEvents.cs @@ -15,8 +15,6 @@ internal class NetEvents : IDisposable #if PROCESS_REQUEST bool _neededProcessRequest; #endif - public AnsiEscapeSequenceRequests EscSeqRequests { get; } = new (); - public NetEvents (ConsoleDriver consoleDriver) { _consoleDriver = consoleDriver ?? throw new ArgumentNullException (nameof (consoleDriver)); @@ -79,15 +77,15 @@ internal class NetEvents : IDisposable return Console.ReadKey (intercept); } - if (AnsiEscapeSequenceRequestUtils.IncompleteCkInfos is null && EscSeqRequests is { Statuses.Count: > 0 }) + if (AnsiEscapeSequenceRequestUtils.IncompleteCkInfos is null && AnsiEscapeSequenceRequests.Statuses.Count > 0) { if (_retries > 1) { - if (EscSeqRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? seqReqStatus) && string.IsNullOrEmpty (seqReqStatus.AnsiRequest.AnsiEscapeSequenceResponse?.Response)) + if (AnsiEscapeSequenceRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? seqReqStatus) && string.IsNullOrEmpty (seqReqStatus.AnsiRequest.AnsiEscapeSequenceResponse?.Response)) { lock (seqReqStatus.AnsiRequest._responseLock) { - EscSeqRequests.Statuses.TryDequeue (out _); + AnsiEscapeSequenceRequests.Statuses.TryDequeue (out _); seqReqStatus.AnsiRequest.RaiseResponseFromInput (null); } @@ -371,21 +369,20 @@ internal class NetEvents : IDisposable { // isMouse is true if it's CSI<, false otherwise AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - EscSeqRequests, - ref newConsoleKeyInfo, - ref key, - cki, - ref mod, - out string c1Control, - out string code, - out string [] values, - out string terminating, - out bool isMouse, - out List mouseFlags, - out Point pos, - out AnsiEscapeSequenceRequestStatus? seqReqStatus, - (f, p) => HandleMouseEvent (MapMouseFlags (f), p) - ); + ref newConsoleKeyInfo, + ref key, + cki, + ref mod, + out string c1Control, + out string code, + out string [] values, + out string terminating, + out bool isMouse, + out List mouseFlags, + out Point pos, + out AnsiEscapeSequenceRequestStatus? seqReqStatus, + (f, p) => HandleMouseEvent (MapMouseFlags (f), p) + ); if (isMouse) { @@ -413,7 +410,7 @@ internal class NetEvents : IDisposable if (!string.IsNullOrEmpty (AnsiEscapeSequenceRequestUtils.InvalidRequestTerminator)) { - if (EscSeqRequests.Statuses.TryDequeue (out AnsiEscapeSequenceRequestStatus? result)) + if (AnsiEscapeSequenceRequests.Statuses.TryDequeue (out AnsiEscapeSequenceRequestStatus? result)) { lock (result.AnsiRequest._responseLock) { diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsConsole.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsConsole.cs index de2649747..63229ae09 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsConsole.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsConsole.cs @@ -110,10 +110,10 @@ internal class WindowsConsole ansiSequence.Append (inputChar); // Check if the sequence has ended with an expected command terminator - if (_mainLoop?.EscSeqRequests is { } && _mainLoop.EscSeqRequests.HasResponse (inputChar.ToString (), out AnsiEscapeSequenceRequestStatus? seqReqStatus)) + if (AnsiEscapeSequenceRequests.HasResponse (inputChar.ToString (), out AnsiEscapeSequenceRequestStatus? seqReqStatus)) { // Finished reading the sequence and remove the enqueued request - _mainLoop.EscSeqRequests.Remove (seqReqStatus); + AnsiEscapeSequenceRequests.Remove (seqReqStatus); lock (seqReqStatus!.AnsiRequest._responseLock) { @@ -130,9 +130,9 @@ internal class WindowsConsole } } - if (readingSequence && !raisedResponse && AnsiEscapeSequenceRequestUtils.IncompleteCkInfos is null && _mainLoop?.EscSeqRequests is { Statuses.Count: > 0 }) + if (readingSequence && !raisedResponse && AnsiEscapeSequenceRequestUtils.IncompleteCkInfos is null && AnsiEscapeSequenceRequests.Statuses.Count > 0) { - _mainLoop.EscSeqRequests.Statuses.TryDequeue (out AnsiEscapeSequenceRequestStatus? seqReqStatus); + AnsiEscapeSequenceRequests.Statuses.TryDequeue (out AnsiEscapeSequenceRequestStatus? seqReqStatus); lock (seqReqStatus!.AnsiRequest._responseLock) { @@ -143,15 +143,15 @@ internal class WindowsConsole _retries = 0; } - else if (AnsiEscapeSequenceRequestUtils.IncompleteCkInfos is null && _mainLoop?.EscSeqRequests is { Statuses.Count: > 0 }) + else if (AnsiEscapeSequenceRequestUtils.IncompleteCkInfos is null && AnsiEscapeSequenceRequests.Statuses.Count > 0) { if (_retries > 1) { - if (_mainLoop.EscSeqRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? seqReqStatus) && string.IsNullOrEmpty (seqReqStatus.AnsiRequest.AnsiEscapeSequenceResponse?.Response)) + if (AnsiEscapeSequenceRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? seqReqStatus) && string.IsNullOrEmpty (seqReqStatus.AnsiRequest.AnsiEscapeSequenceResponse?.Response)) { lock (seqReqStatus.AnsiRequest._responseLock) { - _mainLoop.EscSeqRequests.Statuses.TryDequeue (out _); + AnsiEscapeSequenceRequests.Statuses.TryDequeue (out _); seqReqStatus.AnsiRequest.RaiseResponseFromInput (null); // Clear the terminator for not be enqueued diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsDriver.cs index 07d0904ce..d7275e541 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsDriver.cs @@ -222,7 +222,9 @@ internal class WindowsDriver : ConsoleDriver _waitAnsiResponse.Set (); }; - _mainLoopDriver.EscSeqRequests.Add (ansiRequest, this); + AnsiEscapeSequenceRequests.Add (ansiRequest); + + WriteRaw (ansiRequest.Request); _mainLoopDriver._forceRead = true; } @@ -238,15 +240,15 @@ internal class WindowsDriver : ConsoleDriver { _mainLoopDriver._forceRead = false; - if (_mainLoopDriver.EscSeqRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? request)) + if (AnsiEscapeSequenceRequests.Statuses.TryPeek (out AnsiEscapeSequenceRequestStatus? request)) { - if (_mainLoopDriver.EscSeqRequests.Statuses.Count > 0 + if (AnsiEscapeSequenceRequests.Statuses.Count > 0 && string.IsNullOrEmpty (request.AnsiRequest.AnsiEscapeSequenceResponse?.Response)) { lock (request.AnsiRequest._responseLock) { // Bad request or no response at all - _mainLoopDriver.EscSeqRequests.Statuses.TryDequeue (out _); + AnsiEscapeSequenceRequests.Statuses.TryDequeue (out _); } } } @@ -257,10 +259,7 @@ internal class WindowsDriver : ConsoleDriver } } - internal override void WriteRaw (string ansi) - { - WinConsole?.WriteANSI (ansi); - } + internal override void WriteRaw (string ansi) { WinConsole?.WriteANSI (ansi); } #region Not Implemented diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsMainLoop.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsMainLoop.cs index fb167075d..ca10a693f 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsMainLoop.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsMainLoop.cs @@ -1,5 +1,4 @@ #nullable enable -using System.Collections.Concurrent; namespace Terminal.Gui; @@ -21,7 +20,8 @@ internal class WindowsMainLoop : IMainLoopDriver private readonly ManualResetEventSlim _eventReady = new (false); // The records that we keep fetching - private readonly BlockingCollection _resultQueue = new (new ConcurrentQueue ()); + private readonly Queue _resultQueue = new (); + private readonly ManualResetEventSlim _waitForProbe = new (false); private readonly WindowsConsole? _winConsole; private CancellationTokenSource _eventReadyTokenSource = new (); private readonly CancellationTokenSource _inputHandlerTokenSource = new (); @@ -38,8 +38,6 @@ internal class WindowsMainLoop : IMainLoopDriver } } - public AnsiEscapeSequenceRequests EscSeqRequests { get; } = new (); - void IMainLoopDriver.Setup (MainLoop mainLoop) { _mainLoop = mainLoop; @@ -59,6 +57,7 @@ internal class WindowsMainLoop : IMainLoopDriver bool IMainLoopDriver.EventsPending () { + _waitForProbe.Set (); #if HACK_CHECK_WINCHANGED _winChange.Set (); #endif @@ -105,10 +104,7 @@ internal class WindowsMainLoop : IMainLoopDriver { while (_resultQueue.Count > 0) { - if (_resultQueue.TryTake (out WindowsConsole.InputRecord dequeueResult)) - { - ((WindowsDriver)_consoleDriver).ProcessInput (dequeueResult); - } + ((WindowsDriver)_consoleDriver).ProcessInput (_resultQueue.Dequeue ()); } #if HACK_CHECK_WINCHANGED if (_winChanged) @@ -135,7 +131,9 @@ internal class WindowsMainLoop : IMainLoopDriver } } - _resultQueue.Dispose (); + _waitForProbe?.Dispose (); + + _resultQueue.Clear (); _eventReadyTokenSource.Cancel (); _eventReadyTokenSource.Dispose (); @@ -156,9 +154,9 @@ internal class WindowsMainLoop : IMainLoopDriver { try { - if (_inputHandlerTokenSource.IsCancellationRequested) + if (_inputHandlerTokenSource.IsCancellationRequested && !_forceRead) { - return; + _waitForProbe.Wait (_inputHandlerTokenSource.Token); } if (_resultQueue?.Count == 0 || _forceRead) @@ -167,19 +165,22 @@ internal class WindowsMainLoop : IMainLoopDriver if (result.HasValue) { - _resultQueue!.Add (result.Value); + _resultQueue!.Enqueue (result.Value); } } - if (!_inputHandlerTokenSource.IsCancellationRequested && _resultQueue?.Count > 0) - { - _eventReady.Set (); - } } catch (OperationCanceledException) { return; } + finally + { + if (_inputHandlerTokenSource is { IsCancellationRequested: false }) + { + _eventReady.Set (); + } + } } } diff --git a/UnitTests/Input/AnsiEscapeSequenceRequestUtilsTests.cs b/UnitTests/Input/AnsiEscapeSequenceRequestUtilsTests.cs index c7298d7c4..a9c8f5d05 100644 --- a/UnitTests/Input/AnsiEscapeSequenceRequestUtilsTests.cs +++ b/UnitTests/Input/AnsiEscapeSequenceRequestUtilsTests.cs @@ -10,7 +10,6 @@ public class AnsiEscapeSequenceRequestUtilsTests private Point _arg2; private string _c1Control, _code, _terminating; private ConsoleKeyInfo [] _cki; - private AnsiEscapeSequenceRequests _escSeqReqProc; private bool _isKeyMouse; [CanBeNull] private AnsiEscapeSequenceRequestStatus _seqReqStatus; @@ -30,22 +29,21 @@ public class AnsiEscapeSequenceRequestUtilsTests var expectedCki = new ConsoleKeyInfo ('\u001b', ConsoleKey.Escape, false, false, false); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.Escape, _key); Assert.Equal (0, (int)_mod); @@ -65,22 +63,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = new ('\u0012', ConsoleKey.R, false, true, true); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.R, _key); Assert.Equal (ConsoleModifiers.Alt | ConsoleModifiers.Control, _mod); @@ -100,22 +97,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = new ('r', ConsoleKey.R, false, true, false); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.R, _key); Assert.Equal (ConsoleModifiers.Alt, _mod); @@ -140,22 +136,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = new ('\0', ConsoleKey.F3, false, false, false); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.F3, _key); Assert.Equal (0, (int)_mod); @@ -186,22 +181,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = new ('\0', ConsoleKey.F3, true, false, false); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.F3, _key); Assert.Equal (ConsoleModifiers.Shift, _mod); @@ -232,22 +226,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = new ('\0', ConsoleKey.F3, false, true, false); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.F3, _key); Assert.Equal (ConsoleModifiers.Alt, _mod); @@ -278,22 +271,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = new ('\0', ConsoleKey.F3, true, true, false); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.F3, _key); Assert.Equal (ConsoleModifiers.Shift | ConsoleModifiers.Alt, _mod); @@ -324,22 +316,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = new ('\0', ConsoleKey.F3, false, false, true); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.F3, _key); Assert.Equal (ConsoleModifiers.Control, _mod); @@ -370,22 +361,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = new ('\0', ConsoleKey.F3, true, false, true); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.F3, _key); Assert.Equal (ConsoleModifiers.Shift | ConsoleModifiers.Control, _mod); @@ -416,22 +406,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = new ('\0', ConsoleKey.F3, false, true, true); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.F3, _key); Assert.Equal (ConsoleModifiers.Alt | ConsoleModifiers.Control, _mod); @@ -462,22 +451,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = new ('\0', ConsoleKey.F3, true, true, true); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.F3, _key); Assert.Equal (ConsoleModifiers.Shift | ConsoleModifiers.Alt | ConsoleModifiers.Control, _mod); @@ -511,22 +499,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = default (ConsoleKeyInfo); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (0, (int)_key); Assert.Equal (0, (int)_mod); @@ -561,22 +548,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = default (ConsoleKeyInfo); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (0, (int)_key); Assert.Equal (0, (int)_mod); @@ -616,22 +602,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = default (ConsoleKeyInfo); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (0, (int)_key); Assert.Equal (0, (int)_mod); @@ -664,22 +649,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = default (ConsoleKeyInfo); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (0, (int)_key); Assert.Equal (0, (int)_mod); @@ -719,22 +703,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = default (ConsoleKeyInfo); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (0, (int)_key); Assert.Equal (0, (int)_mod); @@ -788,22 +771,21 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = default (ConsoleKeyInfo); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (0, (int)_key); Assert.Equal (0, (int)_mod); @@ -823,9 +805,9 @@ public class AnsiEscapeSequenceRequestUtilsTests ClearAll (); - Assert.Null (_escSeqReqProc); - _escSeqReqProc = new (); - _escSeqReqProc.Add (new () { Request = "", Terminator = "t" }); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); + AnsiEscapeSequenceRequests.Clear (); + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); _cki = new ConsoleKeyInfo [] { @@ -841,26 +823,25 @@ public class AnsiEscapeSequenceRequestUtilsTests new ('t', 0, false, false, false) }; expectedCki = default (ConsoleKeyInfo); - Assert.Single (_escSeqReqProc.Statuses); - Assert.Equal ("t", _escSeqReqProc.Statuses.ToArray () [^1].AnsiRequest.Terminator); + Assert.Single (AnsiEscapeSequenceRequests.Statuses); + Assert.Equal ("t", AnsiEscapeSequenceRequests.Statuses.ToArray () [^1].AnsiRequest.Terminator); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Empty (_escSeqReqProc.Statuses); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (0, (int)_key); Assert.Equal (0, (int)_mod); @@ -909,22 +890,21 @@ public class AnsiEscapeSequenceRequestUtilsTests var expectedCki = new ConsoleKeyInfo (keyChar, consoleKey, shift, alt, control); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (consoleKey, _key); @@ -976,22 +956,21 @@ public class AnsiEscapeSequenceRequestUtilsTests ConsoleKeyInfo expectedCki = default; AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.None, _key); Assert.Equal (ConsoleModifiers.None, _mod); @@ -1019,23 +998,25 @@ public class AnsiEscapeSequenceRequestUtilsTests expectedCki = default; + // Add a request to avoid assert failure in the DecodeEscSeq method + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); + AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (ConsoleKey.None, _key); @@ -1047,6 +1028,7 @@ public class AnsiEscapeSequenceRequestUtilsTests Assert.False (_isKeyMouse); Assert.Equal ([0], _mouseFlags); Assert.Equal (Point.Empty, _pos); + AnsiEscapeSequenceRequests.HasResponse ("t", out _seqReqStatus); Assert.Null (_seqReqStatus); Assert.Equal (0, (int)_arg1); Assert.Equal (Point.Empty, _arg2); @@ -1073,22 +1055,21 @@ public class AnsiEscapeSequenceRequestUtilsTests var expectedCki = new ConsoleKeyInfo (keyChar, consoleKey, shift, alt, control); AnsiEscapeSequenceRequestUtils.DecodeEscSeq ( - _escSeqReqProc, - ref _newConsoleKeyInfo, - ref _key, - _cki, - ref _mod, - out _c1Control, - out _code, - out _values, - out _terminating, - out _isKeyMouse, - out _mouseFlags, - out _pos, - out _seqReqStatus, - ProcessContinuousButtonPressed - ); - Assert.Null (_escSeqReqProc); + ref _newConsoleKeyInfo, + ref _key, + _cki, + ref _mod, + out _c1Control, + out _code, + out _values, + out _terminating, + out _isKeyMouse, + out _mouseFlags, + out _pos, + out _seqReqStatus, + ProcessContinuousButtonPressed + ); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); Assert.Equal (expectedCki, _newConsoleKeyInfo); Assert.Equal (consoleKey, _key); @@ -1559,7 +1540,7 @@ public class AnsiEscapeSequenceRequestUtilsTests private void ClearAll () { - _escSeqReqProc = default (AnsiEscapeSequenceRequests); + AnsiEscapeSequenceRequests.Clear (); _newConsoleKeyInfo = default (ConsoleKeyInfo); _key = default (ConsoleKey); _cki = default (ConsoleKeyInfo []); diff --git a/UnitTests/Input/AnsiEscapeSequenceRequestsTests.cs b/UnitTests/Input/AnsiEscapeSequenceRequestsTests.cs index 0184ab122..aadcc77b7 100644 --- a/UnitTests/Input/AnsiEscapeSequenceRequestsTests.cs +++ b/UnitTests/Input/AnsiEscapeSequenceRequestsTests.cs @@ -5,66 +5,68 @@ public class AnsiEscapeSequenceRequestsTests [Fact] public void Add_Tests () { - var escSeqReq = new AnsiEscapeSequenceRequests (); - escSeqReq.Add (new () { Request = "", Terminator = "t" }); - Assert.Single (escSeqReq.Statuses); - Assert.Equal ("t", escSeqReq.Statuses.ToArray () [^1].AnsiRequest.Terminator); + AnsiEscapeSequenceRequests.Clear (); + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); + Assert.Single (AnsiEscapeSequenceRequests.Statuses); + Assert.Equal ("t", AnsiEscapeSequenceRequests.Statuses.ToArray () [^1].AnsiRequest.Terminator); - escSeqReq.Add (new () { Request = "", Terminator = "t" }); - Assert.Equal (2, escSeqReq.Statuses.Count); - Assert.Equal ("t", escSeqReq.Statuses.ToArray () [^1].AnsiRequest.Terminator); + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); + Assert.Equal (2, AnsiEscapeSequenceRequests.Statuses.Count); + Assert.Equal ("t", AnsiEscapeSequenceRequests.Statuses.ToArray () [^1].AnsiRequest.Terminator); - escSeqReq = new (); - escSeqReq.Add (new () { Request = "", Terminator = "t" }); - escSeqReq.Add (new () { Request = "", Terminator = "t" }); - Assert.Equal (2, escSeqReq.Statuses.Count); - Assert.Equal ("t", escSeqReq.Statuses.ToArray () [^1].AnsiRequest.Terminator); + AnsiEscapeSequenceRequests.Clear (); + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); + Assert.Equal (2, AnsiEscapeSequenceRequests.Statuses.Count); + Assert.Equal ("t", AnsiEscapeSequenceRequests.Statuses.ToArray () [^1].AnsiRequest.Terminator); - escSeqReq.Add (new () { Request = "", Terminator = "t" }); - Assert.Equal (3, escSeqReq.Statuses.Count); - Assert.Equal ("t", escSeqReq.Statuses.ToArray () [^1].AnsiRequest.Terminator); + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); + Assert.Equal (3, AnsiEscapeSequenceRequests.Statuses.Count); + Assert.Equal ("t", AnsiEscapeSequenceRequests.Statuses.ToArray () [^1].AnsiRequest.Terminator); } [Fact] public void Constructor_Defaults () { - var escSeqReq = new AnsiEscapeSequenceRequests (); - Assert.NotNull (escSeqReq.Statuses); - Assert.Empty (escSeqReq.Statuses); + AnsiEscapeSequenceRequests.Clear (); + Assert.NotNull (AnsiEscapeSequenceRequests.Statuses); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); } [Fact] public void Remove_Tests () { - var escSeqReq = new AnsiEscapeSequenceRequests (); - escSeqReq.Add (new () { Request = "", Terminator = "t" }); - escSeqReq.HasResponse ("t", out AnsiEscapeSequenceRequestStatus seqReqStatus); - escSeqReq.Remove (seqReqStatus); - Assert.Empty (escSeqReq.Statuses); + AnsiEscapeSequenceRequests.Clear (); + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); + AnsiEscapeSequenceRequests.HasResponse ("t", out AnsiEscapeSequenceRequestStatus seqReqStatus); + AnsiEscapeSequenceRequests.Remove (seqReqStatus); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); - escSeqReq.Add (new () { Request = "", Terminator = "t" }); - escSeqReq.Add (new () { Request = "", Terminator = "t" }); - escSeqReq.HasResponse ("t", out seqReqStatus); - escSeqReq.Remove (seqReqStatus); - Assert.Single (escSeqReq.Statuses); - Assert.Equal ("t", escSeqReq.Statuses.ToArray () [^1].AnsiRequest.Terminator); + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); + AnsiEscapeSequenceRequests.HasResponse ("t", out seqReqStatus); + AnsiEscapeSequenceRequests.Remove (seqReqStatus); + Assert.Single (AnsiEscapeSequenceRequests.Statuses); + Assert.Equal ("t", AnsiEscapeSequenceRequests.Statuses.ToArray () [^1].AnsiRequest.Terminator); - escSeqReq.HasResponse ("t", out seqReqStatus); - escSeqReq.Remove (seqReqStatus); - Assert.Empty (escSeqReq.Statuses); + AnsiEscapeSequenceRequests.HasResponse ("t", out seqReqStatus); + AnsiEscapeSequenceRequests.Remove (seqReqStatus); + Assert.Empty (AnsiEscapeSequenceRequests.Statuses); } [Fact] public void Requested_Tests () { - var escSeqReq = new AnsiEscapeSequenceRequests (); - Assert.False (escSeqReq.HasResponse ("t", out AnsiEscapeSequenceRequestStatus seqReqStatus)); + AnsiEscapeSequenceRequests.Clear (); + Assert.False (AnsiEscapeSequenceRequests.HasResponse ("t", out AnsiEscapeSequenceRequestStatus seqReqStatus)); Assert.Null (seqReqStatus); - escSeqReq.Add (new () { Request = "", Terminator = "t" }); - Assert.False (escSeqReq.HasResponse ("r", out seqReqStatus)); - Assert.Null (seqReqStatus); - Assert.True (escSeqReq.HasResponse ("t", out seqReqStatus)); + AnsiEscapeSequenceRequests.Add (new () { Request = "", Terminator = "t" }); + Assert.False (AnsiEscapeSequenceRequests.HasResponse ("r", out seqReqStatus)); Assert.NotNull (seqReqStatus); + Assert.Equal ("t", seqReqStatus.AnsiRequest.Terminator); + Assert.True (AnsiEscapeSequenceRequests.HasResponse ("t", out seqReqStatus)); + Assert.NotNull (seqReqStatus); + Assert.Equal ("t", seqReqStatus.AnsiRequest.Terminator); } }