using XFESystem.Console;
using XfeConsoleApi = XFEExtension.NetCore.XFEConsole.XFEConsole;
namespace XFESystem.ManagedRuntime;
/// <summary>Console API calls are bound to one guest terminal, never to host stdout or files.</summary>
public sealed class TerminalManagedConsole(TerminalTextWriter writer) : IManagedConsole
{
private ConsoleColor _foreground = ConsoleColor.Cyan, _background = ConsoleColor.Black;
private int _written;
public ConsoleColor ForegroundColor
{
get => _foreground;
set { var color = TerminalColor.FromConsoleColor(value); _foreground = value; Control($"\u001b[38;2;{color.Red};{color.Green};{color.Blue}m"); }
}
public ConsoleColor BackgroundColor
{
get => _background;
set { var color = TerminalColor.FromConsoleColor(value); _background = value; Control($"\u001b[48;2;{color.Red};{color.Green};{color.Blue}m"); }
}
public void ResetColor() { _foreground = ConsoleColor.Cyan; _background = ConsoleColor.Black; Control("\u001b[0m"); }
public void Write(string value) { Limit(value.Length); writer.Write(value); }
public void WriteLine(string value) { Limit(value.Length + 2); writer.Write(value); writer.Write("\r\n"); }
public void XfeWriteLine(string value)
{
Limit(value.Length + 2);
var oldWriter = XfeConsoleApi.CurrentConsoleTextWriter;
bool oldDebug = XfeConsoleApi.ShowInDebug, oldLocal = XfeConsoleApi.ShowInLocalConsole, oldLog = XfeConsoleApi.EnableLog;
try
{
XfeConsoleApi.CurrentConsoleTextWriter = new(writer);
XfeConsoleApi.ShowInDebug = false; XfeConsoleApi.ShowInLocalConsole = true; XfeConsoleApi.EnableLog = false;
XfeConsoleApi.WriteLine(value);
}
catch
{
Restore();
throw;
}
Restore();
// The current native exception unwinder does not execute finally clauses.
void Restore()
{
XfeConsoleApi.CurrentConsoleTextWriter = oldWriter;
XfeConsoleApi.ShowInDebug = oldDebug; XfeConsoleApi.ShowInLocalConsole = oldLocal; XfeConsoleApi.EnableLog = oldLog;
}
}
private void Control(string sequence) { Limit(sequence.Length); writer.Write(sequence); }
private void Limit(int count)
{
if (count > ManagedRuntimeCapabilities.MaxOutputCharacters - _written) throw new InvalidOperationException("Managed console output limit exceeded.");
_written += count;
}
}
using XFESystem.Console;
using XfeConsoleApi = XFEExtension.NetCore.XFEConsole.XFEConsole;
namespace XFESystem.ManagedRuntime;
/// <summary>Console API calls are bound to one guest terminal, never to host stdout or files.</summary>
public sealed class TerminalManagedConsole(TerminalTextWriter writer) : IManagedConsole
{
private ConsoleColor _foreground = ConsoleColor.Cyan, _background = ConsoleColor.Black;
private int _written;
public ConsoleColor ForegroundColor
{
get => _foreground;
set { var color = TerminalColor.FromConsoleColor(value); _foreground = value; Control($"\u001b[38;2;{color.Red};{color.Green};{color.Blue}m"); }
}
public ConsoleColor BackgroundColor
{
get => _background;
set { var color = TerminalColor.FromConsoleColor(value); _background = value; Control($"\u001b[48;2;{color.Red};{color.Green};{color.Blue}m"); }
}
public void ResetColor() { _foreground = ConsoleColor.Cyan; _background = ConsoleColor.Black; Control("\u001b[0m"); }
public void Write(string value) { Limit(value.Length); writer.Write(value); }
public void WriteLine(string value) { Limit(value.Length + 2); writer.Write(value); writer.Write("\r\n"); }
public void XfeWriteLine(string value)
{
Limit(value.Length + 2);
var oldWriter = XfeConsoleApi.CurrentConsoleTextWriter;
bool oldDebug = XfeConsoleApi.ShowInDebug, oldLocal = XfeConsoleApi.ShowInLocalConsole, oldLog = XfeConsoleApi.EnableLog;
try
{
XfeConsoleApi.CurrentConsoleTextWriter = new(writer);
XfeConsoleApi.ShowInDebug = false; XfeConsoleApi.ShowInLocalConsole = true; XfeConsoleApi.EnableLog = false;
XfeConsoleApi.WriteLine(value);
}
catch
{
Restore();
throw;
}
Restore();
// The current native exception unwinder does not execute finally clauses.
void Restore()
{
XfeConsoleApi.CurrentConsoleTextWriter = oldWriter;
XfeConsoleApi.ShowInDebug = oldDebug; XfeConsoleApi.ShowInLocalConsole = oldLocal; XfeConsoleApi.EnableLog = oldLog;
}
}
private void Control(string sequence) { Limit(sequence.Length); writer.Write(sequence); }
private void Limit(int count)
{
if (count > ManagedRuntimeCapabilities.MaxOutputCharacters - _written) throw new InvalidOperationException("Managed console output limit exceeded.");
_written += count;
}
}