EscSeqReq.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #nullable enable
  2. namespace Terminal.Gui;
  3. /// <summary>
  4. /// Represents the status of an ANSI escape sequence request made to the terminal using
  5. /// <see cref="EscSeqRequests"/>.
  6. /// </summary>
  7. /// <remarks></remarks>
  8. public class EscSeqReqStatus
  9. {
  10. /// <summary>Creates a new state of escape sequence request.</summary>
  11. /// <param name="ansiRequest">The <see cref="AnsiEscapeSequenceRequest"/> object.</param>
  12. public EscSeqReqStatus (AnsiEscapeSequenceRequest ansiRequest) { AnsiRequest = ansiRequest; }
  13. /// <summary>Gets the Escape Sequence Terminator (e.g. ESC[8t ... t is the terminator).</summary>
  14. public AnsiEscapeSequenceRequest AnsiRequest { get; }
  15. }
  16. // TODO: This class is a singleton. It should use the singleton pattern.
  17. /// <summary>
  18. /// Manages ANSI Escape Sequence requests and responses. The list of <see cref="EscSeqReqStatus"/> contains the
  19. /// status of the request. Each request is identified by the terminator (e.g. ESC[8t ... t is the terminator).
  20. /// </summary>
  21. public class EscSeqRequests
  22. {
  23. /// <summary>
  24. /// Adds a new request for the ANSI Escape Sequence defined by <paramref name="ansiRequest"/>. Adds a
  25. /// <see cref="EscSeqReqStatus"/> instance to <see cref="Statuses"/> list.
  26. /// </summary>
  27. /// <param name="ansiRequest">The <see cref="AnsiEscapeSequenceRequest"/> object.</param>
  28. public void Add (AnsiEscapeSequenceRequest ansiRequest)
  29. {
  30. lock (Statuses)
  31. {
  32. Statuses.Enqueue (new (ansiRequest));
  33. Console.Out.Write (ansiRequest.Request);
  34. Console.Out.Flush ();
  35. Thread.Sleep (100); // Allow time for the terminal to respond
  36. }
  37. }
  38. /// <summary>
  39. /// Indicates if a <see cref="EscSeqReqStatus"/> with the <paramref name="terminator"/> exists in the
  40. /// <see cref="Statuses"/> list.
  41. /// </summary>
  42. /// <param name="terminator"></param>
  43. /// <param name="seqReqStatus"></param>
  44. /// <returns><see langword="true"/> if exist, <see langword="false"/> otherwise.</returns>
  45. public bool HasResponse (string terminator, out EscSeqReqStatus? seqReqStatus)
  46. {
  47. lock (Statuses)
  48. {
  49. Statuses.TryPeek (out seqReqStatus);
  50. var result = seqReqStatus?.AnsiRequest.Terminator == terminator;
  51. if (result)
  52. {
  53. return true;
  54. }
  55. seqReqStatus = null;
  56. return false;
  57. }
  58. }
  59. /// <summary>
  60. /// Removes a request defined by <paramref name="seqReqStatus"/>. If a matching <see cref="EscSeqReqStatus"/> is
  61. /// found and the number of outstanding requests is greater than 0, the number of outstanding requests is decremented.
  62. /// If the number of outstanding requests is 0, the <see cref="EscSeqReqStatus"/> is removed from
  63. /// <see cref="Statuses"/>.
  64. /// </summary>
  65. /// <param name="seqReqStatus">The <see cref="EscSeqReqStatus"/> object.</param>
  66. public void Remove (EscSeqReqStatus? seqReqStatus)
  67. {
  68. lock (Statuses)
  69. {
  70. Statuses.Dequeue ();
  71. }
  72. }
  73. /// <summary>Gets the <see cref="EscSeqReqStatus"/> list.</summary>
  74. public Queue<EscSeqReqStatus> Statuses { get; } = new ();
  75. }