using System;
using System.Collections.Generic;
namespace Terminal.Gui {
///
/// Represents the status of an ANSI escape sequence request made to the terminal using .
///
///
///
public class EscSeqReqStatus {
///
/// Gets the Escape Sequence Termintor (e.g. ESC[8t ... t is the terminator).
///
public string Terminator { get; }
///
/// Gets the number of requests.
///
public int NumRequests { get; }
///
/// Gets the number of unfinished requests.
///
public int NumOutstanding { get; set; }
///
/// Creates a new state of escape sequence request.
///
/// The terminator.
/// The number of requests.
public EscSeqReqStatus (string terminator, int numReq)
{
Terminator = terminator;
NumRequests = NumOutstanding = numReq;
}
}
// 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 EscSeqRequests {
///
/// Gets the list.
///
public List Statuses { get; } = new List ();
///
/// Adds a new request for the ANSI Escape Sequence defined by . Adds a
/// instance to list.
///
/// The terminator.
/// The number of requests.
public void Add (string terminator, int numReq = 1)
{
lock (Statuses) {
var found = Statuses.Find (x => x.Terminator == terminator);
if (found == null) {
Statuses.Add (new EscSeqReqStatus (terminator, numReq));
} else if (found != null && found.NumOutstanding < found.NumRequests) {
found.NumOutstanding = Math.Min (found.NumOutstanding + numReq, found.NumRequests);
}
}
}
///
/// Removes a request defined by . If a matching is found
/// and the number of outstanding
/// requests is greater than 0, the number of outstanding requests is decremented. If the number of outstanding requests
/// is 0, the is removed from .
///
/// The terminating string.
public void Remove (string terminator)
{
lock (Statuses) {
var found = Statuses.Find (x => x.Terminator == terminator);
if (found == null) {
return;
}
if (found != null && found.NumOutstanding == 0) {
Statuses.Remove (found);
} else if (found != null && found.NumOutstanding > 0) {
found.NumOutstanding--;
if (found.NumOutstanding == 0) {
Statuses.Remove (found);
}
}
}
}
///
/// Indicates if a with the exists
/// in the list.
///
///
/// if exist, otherwise.
public bool HasResponse (string terminator)
{
lock (Statuses) {
var found = Statuses.Find (x => x.Terminator == terminator);
if (found == null) {
return false;
}
if (found != null && found.NumOutstanding > 0) {
return true;
} else {
// BUGBUG: Why does an API that returns a bool remove the entry from the list?
// NetDriver and Unit tests never exercise this line of code. Maybe Curses does?
Statuses.Remove (found);
}
return false;
}
}
}
}