1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-14 22:34:09 +02:00
Beef/BeefLibs/corlib/src/Console.bf

222 lines
5.4 KiB
Beef
Raw Normal View History

2019-08-23 11:56:54 -07:00
using System.Text;
using System.IO;
using System.Threading;
2020-05-22 06:05:33 -07:00
using System.Threading.Tasks;
2019-08-23 11:56:54 -07:00
namespace System
{
public static class Console
{
static Encoding InputEncoding = Encoding.ASCII;
static Encoding OutputEncoding = Encoding.ASCII;
2019-08-23 11:56:54 -07:00
static ConsoleColor sForegroundColor = .White;
static ConsoleColor sBackgroundColor = .Black;
2020-05-05 15:30:43 +02:00
static readonly ConsoleColor sOriginalForegroundColor = sForegroundColor;
static readonly ConsoleColor sOriginalBackgroundColor = sBackgroundColor;
2020-05-05 15:30:43 +02:00
public static ConsoleColor ForegroundColor
{
get { return sForegroundColor; }
set { sForegroundColor = value; SetColors(); }
2020-05-05 15:30:43 +02:00
}
public static ConsoleColor BackgroundColor
{
get { return sBackgroundColor; }
set { sBackgroundColor = value; SetColors(); }
2020-05-05 15:30:43 +02:00
}
const uint32 STD_INPUT_HANDLE = (uint32)-10;
const uint32 STD_OUTPUT_HANDLE = (uint32)-11;
const uint32 STD_ERROR_HANDLE = (uint32)-12;
2020-05-05 15:30:43 +02:00
[CRepr]
struct CONSOLE_SCREEN_BUFFER_INFO
{
public uint16[2] mSize;
public uint16[2] mCursorPosition;
public uint16 mAttributes;
public uint16[4] mWindow;
public uint16[2] mMaximumWindowSize;
}
2020-05-06 05:30:29 -07:00
[CLink, StdCall]
static extern int SetConsoleTextAttribute(void* hConsoleOutput, uint16 wAttributes);
2020-05-06 05:30:29 -07:00
[CLink, StdCall]
static extern int GetConsoleScreenBufferInfo(void* hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
2020-05-06 05:30:29 -07:00
[CLink, StdCall]
static extern void* GetStdHandle(uint32 nStdHandle);
#if BF_PLATFORM_WINDOWS
public static this()
{
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO consoleInfo = .();
if (GetConsoleScreenBufferInfo(handle, out consoleInfo) != 0)
{
sOriginalForegroundColor.ConsoleTextAttribute = (uint8)(consoleInfo.mAttributes & 0xF);
sOriginalBackgroundColor.ConsoleTextAttribute = (uint8)(consoleInfo.mAttributes >> 4);
}
}
#endif
2020-05-05 15:30:43 +02:00
2019-08-23 11:56:54 -07:00
static StreamWriter OpenStreamWriter(Platform.BfpFileStdKind stdKind, ref StreamWriter outStreamWriter)
{
if (outStreamWriter == null)
{
FileStream fileStream = new .();
Stream stream = fileStream;
if (fileStream.OpenStd(stdKind) case .Err)
{
DeleteAndNullify!(fileStream);
stream = new NullStream();
}
StreamWriter newStreamWriter = new StreamWriter(stream, InputEncoding, 4096, true);
newStreamWriter.AutoFlush = true;
let prevValue = Interlocked.CompareExchange(ref outStreamWriter, null, newStreamWriter);
if (prevValue != null)
{
// This was already set - race condition
delete newStreamWriter;
return prevValue;
}
return newStreamWriter;
}
return outStreamWriter;
}
static StreamReader OpenStreamReader(Platform.BfpFileStdKind stdKind, ref StreamReader outStreamReader)
{
if (outStreamReader == null)
{
FileStream fileStream = new .();
Stream stream = fileStream;
if (fileStream.OpenStd(stdKind) case .Err)
{
DeleteAndNullify!(fileStream);
stream = new NullStream();
}
StreamReader newStreamReader = new StreamReader(stream, InputEncoding, false, 4096, true);
let prevValue = Interlocked.CompareExchange(ref outStreamReader, null, newStreamReader);
if (prevValue != null)
{
// This was already set - race condition
delete newStreamReader;
return prevValue;
}
return newStreamReader;
}
return outStreamReader;
}
public static volatile StreamWriter mOut ~ delete _;
public static StreamWriter Out
{
get
{
return OpenStreamWriter(.Out, ref mOut);
}
}
public static volatile StreamWriter mError ~ delete _;
public static StreamWriter Error
{
get
{
return OpenStreamWriter(.Error, ref mError);
}
}
public static volatile StreamReader mIn ~ delete _;
public static StreamReader In
{
get
{
return OpenStreamReader(.In, ref mIn);
}
}
2020-05-22 11:06:20 +02:00
public static Result<char8> Read() => In.Read();
public static Result<void> ReadLine(String strBuffer) => In.ReadLine(strBuffer);
public static Task<String> ReadLineAsync() => In.ReadLineAsync();
public static Result<void> ReadToEnd(String outText) => In.ReadToEnd(outText);
2019-08-23 11:56:54 -07:00
public static void Write(String line)
{
Out.Write(line).IgnoreError();
}
public static void Write(String fmt, params Object[] args)
{
2020-03-25 09:17:53 -07:00
String str = scope String(256);
2019-08-23 11:56:54 -07:00
str.AppendF(fmt, params args);
Write(str);
}
public static void Write(Object obj)
{
2020-03-25 09:17:53 -07:00
String str = scope String(256);
obj.ToString(str);
Write(str);
}
2019-08-23 11:56:54 -07:00
2020-03-25 09:17:53 -07:00
public static void WriteLine()
{
Out.Write("\n").IgnoreError();
}
2019-08-23 11:56:54 -07:00
public static void WriteLine(String line)
{
Out.WriteLine(line).IgnoreError();
}
public static void WriteLine(StringView fmt, params Object[] args)
{
2020-03-25 09:17:53 -07:00
String str = scope String(256);
2019-08-23 11:56:54 -07:00
str.AppendF(fmt, params args);
WriteLine(str);
}
2020-03-25 21:50:34 +08:00
public static void WriteLine(Object obj)
{
2020-03-25 09:17:53 -07:00
String str = scope String(256);
2020-03-25 21:50:34 +08:00
obj.ToString(str);
WriteLine(str);
}
2020-05-05 15:30:43 +02:00
public static void ResetColor()
{
sForegroundColor = sOriginalForegroundColor;
sBackgroundColor = sOriginalBackgroundColor;
2020-05-05 15:30:43 +02:00
#if !BF_PLATFORM_WINDOWS
Write("\x1B[0m");
#endif
}
static void SetColors()
2020-05-05 15:30:43 +02:00
{
#if BF_PLATFORM_WINDOWS
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
let fgColor = ForegroundColor.ConsoleTextAttribute;
let bgColor = BackgroundColor.ConsoleTextAttribute;
2020-05-05 15:30:43 +02:00
SetConsoleTextAttribute(handle, bgColor * 16 + fgColor);
#else
2020-05-06 17:41:08 -07:00
Write("\x1B[{}m", ForegroundColor.AnsiCode);
Write("\x1B[{}m", BackgroundColor.AnsiCode + 10);
2020-05-05 15:30:43 +02:00
#endif
}
2019-08-23 11:56:54 -07:00
}
}