/
EvilBeaver
/
OneScript
Обзор
Документация
Войти
/
EvilBeaver
/
OneScript
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
v2.0.0
src/OneScript.StandardLibrary/Text/ConsoleContext.cs
284 строки
11 KB
Andrei Ovsiankin
Merge pull request #1533 from Bayselonarrend/feature/eng-synonyms-refinement
28 май 2025, 18:09
Не верифицирован
28 май 2025, 18:09
bd084c3
Код
Авторство
О чём код?
/*---------------------------------------------------------- This Source Code Form is subject to the terms of the Mozilla Public License, v.2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. ----------------------------------------------------------*/ using System; using System.IO; using OneScript.Contexts; using OneScript.Exceptions; using OneScript.Execution; using OneScript.StandardLibrary.Binary; using OneScript.Values; using ScriptEngine.Machine; using ScriptEngine.Machine.Contexts; namespace OneScript.StandardLibrary.Text { /// <summary> /// Класс представляет собой инструмент доступа к системной консоли. /// Предназначен для низкоуровнего манипулирования выводом в консоль. /// /// Поддерживается регистрация обработчика для нажатия Ctrl+C. /// Обработчик регистрируется для события с именем CancelKeyPressed. Стоит учитывать, что обработчик вызывается /// в отдельном потоке и необходимо помнить о потокобезопасности общих данных. /// /// </summary> /// <example> /// Перем Хватит; /// /// Процедура Обработчик(Отказ) /// Сообщить("Обработчик остановки вызван", СтатусСообщения.Важное); /// Отказ = Истина; // не даем системе убить процесс /// Хватит = Истина; // выставим свой флаг завершения цикла /// КонецПроцедуры /// /// Хватит = Ложь; /// ДобавитьОбработчик Консоль.CancelKeyPressed, Обработчик; /// /// Пока Не Хватит Цикл /// Сообщить("Пинг", СтатусСообщения.Информация); /// Приостановить(1000); /// Сообщить("Понг", СтатусСообщения.Информация); /// Приостановить(1000); /// КонецЦикла; /// /// Сообщить("Мягкая остановка процесса", СтатусСообщения.Информация); /// </example> [ContextClass("Консоль", "Console")] public class ConsoleContext : AutoContext<ConsoleContext> { private readonly ExecutionContext _executionContext; public ConsoleContext(ExecutionContext executionContext) { _executionContext = executionContext; Console.CancelKeyPress += ConsoleOnCancelKeyPress; } [ContextProperty("НажатаКлавиша", "KeyPressed")] public bool HasKey => Console.KeyAvailable; [ContextProperty("КурсорЛево", "CursorLeft")] public int XPos { get => Console.CursorLeft; set => Console.CursorLeft = Math.Min(value, Console.WindowWidth-1); } [ContextProperty("КурсорВерх", "CursorTop")] public int YPos { get => Console.CursorTop; set => Console.CursorTop = Math.Min(value, Console.WindowHeight-1); } [ContextMethod("ПрочитатьСтроку", "ReadLine")] public string ReadLine() { return Console.ReadLine(); } [ContextMethod("Прочитать", "Read")] public int ReadKey() { var kki = Console.ReadKey(true); return (int)kki.Key; } [ContextMethod("Очистить", "Clear")] public void Clear() { Console.Clear(); } [ContextMethod("ВывестиСтроку", "WriteLine")] public void WriteLine(string text) { Console.WriteLine(text); } [ContextMethod("Вывести", "Write")] public void Write(string text) { Console.Write(text); } [ContextProperty("Ширина", "Width")] public int Width => Console.WindowWidth; [ContextProperty("Высота", "Height")] public int Height => Console.WindowHeight; [ContextMethod("ВидимостьКурсора", "CursorVisible")] public bool CursorVisible(bool visible) { bool oldVal = Console.CursorVisible; Console.CursorVisible = visible; return oldVal; } [ContextProperty("ЦветТекста", "TextColor")] public ClrEnumValueWrapper<ConsoleColor> TextColor { get => ConsoleColorEnum.Instance.TryGetFromNativeValue(Console.ForegroundColor) ?? ConsoleColorEnum.Instance.FromNativeValue(ConsoleColor.Gray); set => Console.ForegroundColor = value.UnderlyingValue; } [ContextProperty("ЦветФона", "BackgroundColor")] public ClrEnumValueWrapper<ConsoleColor> BackgroundColor { get => ConsoleColorEnum.Instance.TryGetFromNativeValue(Console.BackgroundColor) ?? ConsoleColorEnum.Instance.FromNativeValue(ConsoleColor.Black); set => Console.BackgroundColor = value.UnderlyingValue; } /// <summary> /// Возвращает или задает кодировку консоли, используемую при чтении входных данных. /// </summary> /// <returns>КодировкаТекста</returns> [ContextProperty("КодировкаВходногоПотока", "InputEncoding")] public IValue InputEncoding { get { var encodingEnum = _executionContext.GlobalInstances.GetInstance<TextEncodingEnum>(); return encodingEnum.GetValue(Console.InputEncoding); } set { Console.InputEncoding = TextEncodingEnum.GetEncoding(value); } } /// <summary> /// Сбрасывает цвета консоли к их исходному состоянию /// </summary> [ContextMethod("СброситьЦвет", "ResetColor")] public void ResetColor() { Console.ResetColor(); } /// <summary> /// Возвращает или задает кодировку консоли, используемую при выводе данных. /// </summary> /// <returns>КодировкаТекста</returns> [ContextProperty("КодировкаВыходногоПотока", "OutputEncoding")] public IValue OutputEncoding { get { var encodingEnum = _executionContext.GlobalInstances.GetInstance<TextEncodingEnum>(); return encodingEnum.GetValue(Console.OutputEncoding); } set { Console.OutputEncoding = TextEncodingEnum.GetEncoding(value); } } /// <summary> /// Воспроизводит звуковой сигнал. /// </summary> [ContextMethod("Сигнал", "Beep")] public void Beep() { Console.Beep(); } /// <summary> /// Получает системный поток ввода stdin /// </summary> /// <returns>Поток</returns> [ContextMethod("ОткрытьСтандартныйПотокВвода", "OpenStandardInput")] public GenericStream OpenStandardInput() { var stream = Console.OpenStandardInput(); var streamWithTimeout = new StreamWithTimeout(stream); return new GenericStream(streamWithTimeout, true); } /// <summary> /// Получает системный поток вывода ошибок stderr /// </summary> /// <returns>Поток</returns> [ContextMethod("ОткрытьСтандартныйПотокОшибок", "OpenStandardError")] public GenericStream OpenStandardError() { var stream = Console.OpenStandardError(); return new GenericStream(stream); } /// <summary> /// Получает системный поток вывода stdout /// </summary> /// <returns>Поток</returns> [ContextMethod("ОткрытьСтандартныйПотокВывода", "OpenStandardOutput")] public GenericStream OpenStandardOutput() { var stream = Console.OpenStandardOutput(); return new GenericStream(stream); } /// <summary> /// Глобально переопределяет стандартный вывод и направляет в другой поток /// </summary> /// <param name="target">Поток назначения</param> [ContextMethod("УстановитьПотокВывода", "SetOutput")] public void SetOutput(IValue target) { if (!(target.AsObject() is IStreamWrapper stream)) throw RuntimeException.InvalidArgumentType(nameof(target)); var writer = new StreamWriter(stream.GetUnderlyingStream(), Console.OutputEncoding) { AutoFlush = true, }; Console.SetOut(writer); } /// <summary> /// Глобально переопределяет стандартный поток ошибок и направляет в другой поток /// </summary> /// <param name="target">Поток назначения</param> [ContextMethod("УстановитьПотокОшибок", "SetError")] public void SetError(IValue target) { if (!(target.AsObject() is IStreamWrapper stream)) throw RuntimeException.InvalidArgumentType(nameof(target)); var writer = new StreamWriter(stream.GetUnderlyingStream()); Console.SetError(writer); } public const string ConsoleCancelKeyEvent = "CancelKeyPressed"; private void ConsoleOnCancelKeyPress(object sender, ConsoleCancelEventArgs e) { if (e.SpecialKey != ConsoleSpecialKey.ControlC) return; // Сначала проверим, что события вообще включены var eventProcessor = _executionContext.Services.TryResolve<IEventProcessor>(); if (eventProcessor == null) return; var process = _executionContext.Services.Resolve<IBslProcessFactory>().NewProcess(); var cancelVar = Variable.Create(BslBooleanValue.False, "Cancel"); var reference = Variable.CreateReference(cancelVar, "Cancel"); var args = new IValue[] { reference }; eventProcessor.HandleEvent(this, ConsoleCancelKeyEvent, args, process); e.Cancel = reference.Value.AsBoolean(); } } }