From 8353d993770a9808afc6bf7fdd3ef33513875fa4 Mon Sep 17 00:00:00 2001 From: F4lc0131 Date: Tue, 5 Jan 2021 00:31:36 +0100 Subject: [PATCH 1/6] Add files via upload --- .../System/ConsoleImpl.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs b/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs index 3c6af9d5ce..03d319108b 100644 --- a/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs +++ b/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs @@ -431,8 +431,23 @@ public static ConsoleKeyInfo ReadKey(bool intercept) return new ConsoleKeyInfo(key.KeyChar, key.Key.ToConsoleKey(), xShift, xAlt, xControl); } + /// + /// This will contain the context that locked the Console for the ReadLine() + /// + private static Core.Processing.ProcessContext.Context LockContext = null; + /// + /// This will contain the queue where threads have to wait before accessing the ReadLine method + /// + private static List queue = new List(); + private static List old = null; public static String ReadLine() { + if (LockContext is null) LockContext = Core.Processing.ProcessContext.m_CurrentContext; //if nobody locked the Console, just lock it + else if (LockContext != Core.Processing.ProcessContext.m_CurrentContext) + { + queue.Add(Core.Processing.ProcessContext.m_CurrentContext); + while (LockContext != Core.Processing.ProcessContext.m_CurrentContext) ; + } var xConsole = GetConsole(); if (xConsole == null) { @@ -529,6 +544,19 @@ public static String ReadLine() WriteLine(); char[] final = chars.ToArray(); + //if there's some process queued, we just set the first as the main and queue the otherones + if (queue.Count > 0) + { + Cosmos.HAL.Global.mDebugger.Send($"Dequeuing {queue[0].name} and locking console to it"); + LockContext = queue[0]; + old = queue; + queue = new List(); + foreach (Core.Processing.ProcessContext.Context context in old) + { + if (context != LockContext) + queue.Add(context); + } + } return new string(final); } From 261120443767865b9767e2b73d5fc455d40bdb41 Mon Sep 17 00:00:00 2001 From: F4lc0131 Date: Tue, 5 Jan 2021 01:06:55 +0100 Subject: [PATCH 2/6] Removed some useless stuff --- .../System/ConsoleImpl.cs | 1438 ++++++++--------- 1 file changed, 716 insertions(+), 722 deletions(-) diff --git a/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs b/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs index 03d319108b..8f9cf2ee93 100644 --- a/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs +++ b/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs @@ -1,553 +1,547 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Cosmos.System; -using IL2CPU.API; -using IL2CPU.API.Attribs; - -namespace Cosmos.System_Plugs.System -{ - [Plug(Target = typeof (global::System.Console))] - public static class ConsoleImpl - { - private static ConsoleColor mForeground = ConsoleColor.White; - private static ConsoleColor mBackground = ConsoleColor.Black; - private static Encoding ConsoleInputEncoding = Encoding.ASCII; - private static Encoding ConsoleOutputEncoding = Encoding.ASCII; - - private static readonly Cosmos.System.Console mFallbackConsole = new Cosmos.System.Console(null); - - private static Cosmos.System.Console GetConsole() - { - return mFallbackConsole; - } - - public static ConsoleColor get_BackgroundColor() - { - return mBackground; - } - - public static void set_BackgroundColor(ConsoleColor value) - { - mBackground = value; - //Cosmos.HAL.Global.TextScreen.SetColors(mForeground, mBackground); - if (GetConsole() != null) GetConsole().Background = value; - } - - public static int get_BufferHeight() - { - WriteLine("Not implemented: get_BufferHeight"); - return -1; - } - - public static void set_BufferHeight(int aHeight) - { - WriteLine("Not implemented: set_BufferHeight"); - } - - public static int get_BufferWidth() - { - WriteLine("Not implemented: get_BufferWidth"); - return -1; - } - - public static void set_BufferWidth(int aWidth) - { - WriteLine("Not implemented: set_BufferWidth"); - } - - public static bool get_CapsLock() - { - return Global.CapsLock; - } - - public static int get_CursorLeft() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return 0; - } - return GetConsole().X; - } - - public static void set_CursorLeft(int x) - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - - if (x < get_WindowWidth()) - { - xConsole.X = x; - } - else - { - WriteLine("x must be lower than the console width!"); - } - } - - public static int get_CursorSize() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return 0; - } - return xConsole.CursorSize; - } - - public static void set_CursorSize(int aSize) - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - xConsole.CursorSize = aSize; - } - - public static int get_CursorTop() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return 0; - } - return GetConsole().Y; - } - - public static void set_CursorTop(int y) - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - - if (y < get_WindowHeight()) - { - xConsole.Y = y; - } - else - { - WriteLine("y must be lower than the console height!"); - } - } - - public static bool get_CursorVisible() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - return false; - } - return GetConsole().CursorVisible; - } - - public static void set_CursorVisible(bool value) - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - xConsole.CursorVisible = value; - } - - - //public static TextWriter get_Error() { - // WriteLine("Not implemented: get_Error"); - // return null; - //} - - public static ConsoleColor get_ForegroundColor() - { - return mForeground; - } - - public static void set_ForegroundColor(ConsoleColor value) - { - mForeground = value; - //Cosmos.HAL.Global.TextScreen.SetColors(mForeground, mBackground); - if (GetConsole() != null) GetConsole().Foreground = value; - } - - //public static TextReader get_In() - //{ - // WriteLine("Not implemented: get_In"); - // return null; - //} - - public static Encoding get_InputEncoding() - { - return ConsoleInputEncoding; - } - - public static void set_InputEncoding(Encoding value) - { - ConsoleInputEncoding = value; - } - - public static Encoding get_OutputEncoding() - { - return ConsoleOutputEncoding; - } - - - public static void set_OutputEncoding(Encoding value) - { - ConsoleOutputEncoding = value; - } - - public static bool get_KeyAvailable() - { - return KeyboardManager.KeyAvailable; - } - - public static int get_LargestWindowHeight() - { - WriteLine("Not implemented: get_LargestWindowHeight"); - return -1; - } - - public static int get_LargestWindowWidth() - { - WriteLine("Not implemented: get_LargestWindowWidth"); - return -1; - } - - public static bool get_NumberLock() - { - return Global.NumLock; - } - - //public static TextWriter get_Out() { - // WriteLine("Not implemented: get_Out"); - // return null; - //} - - public static string get_Title() - { - WriteLine("Not implemented: get_Title"); - return string.Empty; - } - - public static void set_Title(string value) - { - WriteLine("Not implemented: set_Title"); - } - - public static bool get_TreatControlCAsInput() - { - WriteLine("Not implemented: get_TreatControlCAsInput"); - return false; - } - - public static void set_TreatControlCAsInput(bool value) - { - WriteLine("Not implemented: set_TreatControlCAsInput"); - } - - public static int get_WindowHeight() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return 25; - } - return GetConsole().Rows; - } - - public static void set_WindowHeight(int value) - { - WriteLine("Not implemented: set_WindowHeight"); - } - - public static int get_WindowLeft() - { - WriteLine("Not implemented: get_WindowLeft"); - return -1; - } - - public static void set_WindowLeft(int value) - { - WriteLine("Not implemented: set_WindowLeft"); - } - - public static int get_WindowTop() - { - WriteLine("Not implemented: get_WindowTop"); - return -1; - } - - public static void set_WindowTop(int value) - { - WriteLine("Not implemented: set_WindowTop"); - } - - public static int get_WindowWidth() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return 85; - } - return GetConsole().Cols; - } - - public static void set_WindowWidth(int value) - { - WriteLine("Not implemented: set_WindowWidth"); - } - - /// - /// The ArgumentOutOfRangeException check is now done at driver level in PCSpeaker - is it still needed here? - /// - /// - /// - public static void Beep(int aFrequency, int aDuration) - { - if (aFrequency < 37 || aFrequency > 32767) - { - throw new ArgumentOutOfRangeException("Frequency must be between 37 and 32767Hz"); - } - - if (aDuration <= 0) - { - throw new ArgumentOutOfRangeException("Duration must be more than 0"); - } - - PCSpeaker.Beep((uint) aFrequency, (uint) aDuration); - } - - /// - /// Beep() is pure CIL - /// Default implementation beeps for 200 milliseconds at 800 hertz - /// In Cosmos, these are Cosmos.System.Duration.Default and Cosmos.System.Notes.Default respectively, - /// and are used when there are no params - /// https://docs.microsoft.com/en-us/dotnet/api/system.console.beep?view=netcore-2.0 - /// - public static void Beep() - { - PCSpeaker.Beep(); - } - - //TODO: Console uses TextWriter - intercept and plug it instead - public static void Clear() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - GetConsole().Clear(); - } - - // MoveBufferArea(int, int, int, int, int, int) is pure CIL - - public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, - int targetLeft, int targetTop, Char sourceChar, ConsoleColor sourceForeColor, ConsoleColor sourceBackColor) - { - WriteLine("Not implemented: MoveBufferArea"); - } - - //public static Stream OpenStandardError() { - // WriteLine("Not implemented: OpenStandardError"); - //} - - //public static Stream OpenStandardError(int bufferSize) { - // WriteLine("Not implemented: OpenStandardError"); - //} - - //public static Stream OpenStandardInput(int bufferSize) { - // WriteLine("Not implemented: OpenStandardInput"); - //} - - //public static Stream OpenStandardInput() { - // WriteLine("Not implemented: OpenStandardInput"); - //} - - //public static Stream OpenStandardOutput(int bufferSize) { - // WriteLine("Not implemented: OpenStandardOutput"); - //} - - //public static Stream OpenStandardOutput() { - // WriteLine("Not implemented: OpenStandardOutput"); - //} - - public static int Read() - { - // TODO special cases, if needed, that returns -1 - KeyEvent xResult; - - if (KeyboardManager.TryReadKey(out xResult)) - { - return xResult.KeyChar; - } - else - { - return -1; - } - } - - public static ConsoleKeyInfo ReadKey() - { - return ReadKey(false); - } - - // ReadKey() pure CIL - - public static ConsoleKeyInfo ReadKey(bool intercept) - { - var key = KeyboardManager.ReadKey(); - if (intercept == false && key.KeyChar != '\0') - { - Write(key.KeyChar); - } - - //TODO: Plug HasFlag and use the next 3 lines instead of the 3 following lines - - //bool xShift = key.Modifiers.HasFlag(ConsoleModifiers.Shift); - //bool xAlt = key.Modifiers.HasFlag(ConsoleModifiers.Alt); - //bool xControl = key.Modifiers.HasFlag(ConsoleModifiers.Control); - - bool xShift = (key.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift; - bool xAlt = (key.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt; - bool xControl = (key.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control; - - return new ConsoleKeyInfo(key.KeyChar, key.Key.ToConsoleKey(), xShift, xAlt, xControl); - } - +using System; +using System.Collections.Generic; +using System.Text; +using Cosmos.System; +using IL2CPU.API; +using IL2CPU.API.Attribs; + +namespace Cosmos.System_Plugs.System +{ + [Plug(Target = typeof (global::System.Console))] + public static class ConsoleImpl + { + private static ConsoleColor mForeground = ConsoleColor.White; + private static ConsoleColor mBackground = ConsoleColor.Black; + private static Encoding ConsoleInputEncoding = Encoding.ASCII; + private static Encoding ConsoleOutputEncoding = Encoding.ASCII; + + private static readonly Cosmos.System.Console mFallbackConsole = new Cosmos.System.Console(null); + + private static Cosmos.System.Console GetConsole() + { + return mFallbackConsole; + } + + public static ConsoleColor get_BackgroundColor() + { + return mBackground; + } + + public static void set_BackgroundColor(ConsoleColor value) + { + mBackground = value; + //Cosmos.HAL.Global.TextScreen.SetColors(mForeground, mBackground); + if (GetConsole() != null) GetConsole().Background = value; + } + + public static int get_BufferHeight() + { + WriteLine("Not implemented: get_BufferHeight"); + return -1; + } + + public static void set_BufferHeight(int aHeight) + { + WriteLine("Not implemented: set_BufferHeight"); + } + + public static int get_BufferWidth() + { + WriteLine("Not implemented: get_BufferWidth"); + return -1; + } + + public static void set_BufferWidth(int aWidth) + { + WriteLine("Not implemented: set_BufferWidth"); + } + + public static bool get_CapsLock() + { + return Global.CapsLock; + } + + public static int get_CursorLeft() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return 0; + } + return GetConsole().X; + } + + public static void set_CursorLeft(int x) + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + + if (x < get_WindowWidth()) + { + xConsole.X = x; + } + else + { + WriteLine("x must be lower than the console width!"); + } + } + + public static int get_CursorSize() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return 0; + } + return xConsole.CursorSize; + } + + public static void set_CursorSize(int aSize) + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + xConsole.CursorSize = aSize; + } + + public static int get_CursorTop() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return 0; + } + return GetConsole().Y; + } + + public static void set_CursorTop(int y) + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + + if (y < get_WindowHeight()) + { + xConsole.Y = y; + } + else + { + WriteLine("y must be lower than the console height!"); + } + } + + public static bool get_CursorVisible() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + return false; + } + return GetConsole().CursorVisible; + } + + public static void set_CursorVisible(bool value) + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + xConsole.CursorVisible = value; + } + + + //public static TextWriter get_Error() { + // WriteLine("Not implemented: get_Error"); + // return null; + //} + + public static ConsoleColor get_ForegroundColor() + { + return mForeground; + } + + public static void set_ForegroundColor(ConsoleColor value) + { + mForeground = value; + //Cosmos.HAL.Global.TextScreen.SetColors(mForeground, mBackground); + if (GetConsole() != null) GetConsole().Foreground = value; + } + + //public static TextReader get_In() + //{ + // WriteLine("Not implemented: get_In"); + // return null; + //} + + public static Encoding get_InputEncoding() + { + return ConsoleInputEncoding; + } + + public static void set_InputEncoding(Encoding value) + { + ConsoleInputEncoding = value; + } + + public static Encoding get_OutputEncoding() + { + return ConsoleOutputEncoding; + } + + + public static void set_OutputEncoding(Encoding value) + { + ConsoleOutputEncoding = value; + } + + public static bool get_KeyAvailable() + { + return KeyboardManager.KeyAvailable; + } + + public static int get_LargestWindowHeight() + { + WriteLine("Not implemented: get_LargestWindowHeight"); + return -1; + } + + public static int get_LargestWindowWidth() + { + WriteLine("Not implemented: get_LargestWindowWidth"); + return -1; + } + + public static bool get_NumberLock() + { + return Global.NumLock; + } + + //public static TextWriter get_Out() { + // WriteLine("Not implemented: get_Out"); + // return null; + //} + + public static string get_Title() + { + WriteLine("Not implemented: get_Title"); + return string.Empty; + } + + public static void set_Title(string value) + { + WriteLine("Not implemented: set_Title"); + } + + public static bool get_TreatControlCAsInput() + { + WriteLine("Not implemented: get_TreatControlCAsInput"); + return false; + } + + public static void set_TreatControlCAsInput(bool value) + { + WriteLine("Not implemented: set_TreatControlCAsInput"); + } + + public static int get_WindowHeight() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return 25; + } + return GetConsole().Rows; + } + + public static void set_WindowHeight(int value) + { + WriteLine("Not implemented: set_WindowHeight"); + } + + public static int get_WindowLeft() + { + WriteLine("Not implemented: get_WindowLeft"); + return -1; + } + + public static void set_WindowLeft(int value) + { + WriteLine("Not implemented: set_WindowLeft"); + } + + public static int get_WindowTop() + { + WriteLine("Not implemented: get_WindowTop"); + return -1; + } + + public static void set_WindowTop(int value) + { + WriteLine("Not implemented: set_WindowTop"); + } + + public static int get_WindowWidth() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return 85; + } + return GetConsole().Cols; + } + + public static void set_WindowWidth(int value) + { + WriteLine("Not implemented: set_WindowWidth"); + } + /// - /// This will contain the context that locked the Console for the ReadLine() - /// - private static Core.Processing.ProcessContext.Context LockContext = null; + /// The ArgumentOutOfRangeException check is now done at driver level in PCSpeaker - is it still needed here? + /// + /// + /// + public static void Beep(int aFrequency, int aDuration) + { + if (aFrequency < 37 || aFrequency > 32767) + { + throw new ArgumentOutOfRangeException("Frequency must be between 37 and 32767Hz"); + } + + if (aDuration <= 0) + { + throw new ArgumentOutOfRangeException("Duration must be more than 0"); + } + + PCSpeaker.Beep((uint) aFrequency, (uint) aDuration); + } + /// - /// This will contain the queue where threads have to wait before accessing the ReadLine method - /// - private static List queue = new List(); + /// Beep() is pure CIL + /// Default implementation beeps for 200 milliseconds at 800 hertz + /// In Cosmos, these are Cosmos.System.Duration.Default and Cosmos.System.Notes.Default respectively, + /// and are used when there are no params + /// https://docs.microsoft.com/en-us/dotnet/api/system.console.beep?view=netcore-2.0 + /// + public static void Beep() + { + PCSpeaker.Beep(); + } + + //TODO: Console uses TextWriter - intercept and plug it instead + public static void Clear() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + GetConsole().Clear(); + } + + // MoveBufferArea(int, int, int, int, int, int) is pure CIL + + public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, + int targetLeft, int targetTop, Char sourceChar, ConsoleColor sourceForeColor, ConsoleColor sourceBackColor) + { + WriteLine("Not implemented: MoveBufferArea"); + } + + //public static Stream OpenStandardError() { + // WriteLine("Not implemented: OpenStandardError"); + //} + + //public static Stream OpenStandardError(int bufferSize) { + // WriteLine("Not implemented: OpenStandardError"); + //} + + //public static Stream OpenStandardInput(int bufferSize) { + // WriteLine("Not implemented: OpenStandardInput"); + //} + + //public static Stream OpenStandardInput() { + // WriteLine("Not implemented: OpenStandardInput"); + //} + + //public static Stream OpenStandardOutput(int bufferSize) { + // WriteLine("Not implemented: OpenStandardOutput"); + //} + + //public static Stream OpenStandardOutput() { + // WriteLine("Not implemented: OpenStandardOutput"); + //} + + public static int Read() + { + // TODO special cases, if needed, that returns -1 + KeyEvent xResult; + + if (KeyboardManager.TryReadKey(out xResult)) + { + return xResult.KeyChar; + } + else + { + return -1; + } + } + + public static ConsoleKeyInfo ReadKey() + { + return ReadKey(false); + } + + // ReadKey() pure CIL + + public static ConsoleKeyInfo ReadKey(bool intercept) + { + var key = KeyboardManager.ReadKey(); + if (intercept == false && key.KeyChar != '\0') + { + Write(key.KeyChar); + } + + //TODO: Plug HasFlag and use the next 3 lines instead of the 3 following lines + + //bool xShift = key.Modifiers.HasFlag(ConsoleModifiers.Shift); + //bool xAlt = key.Modifiers.HasFlag(ConsoleModifiers.Alt); + //bool xControl = key.Modifiers.HasFlag(ConsoleModifiers.Control); + + bool xShift = (key.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift; + bool xAlt = (key.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt; + bool xControl = (key.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control; + + return new ConsoleKeyInfo(key.KeyChar, key.Key.ToConsoleKey(), xShift, xAlt, xControl); + } + + private static Core.Processing.ProcessContext.Context LockContext = null; + private static List queue = new List(); private static List old = null; - public static String ReadLine() - { - if (LockContext is null) LockContext = Core.Processing.ProcessContext.m_CurrentContext; //if nobody locked the Console, just lock it + public static String ReadLine() + { + if (LockContext == null) LockContext = Core.Processing.ProcessContext.m_CurrentContext; //if nobody locked the Console, just lock it else if (LockContext != Core.Processing.ProcessContext.m_CurrentContext) { queue.Add(Core.Processing.ProcessContext.m_CurrentContext); while (LockContext != Core.Processing.ProcessContext.m_CurrentContext) ; - } - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return null; - } - List chars = new List(32); - KeyEvent current; - int currentCount = 0; - - while ((current = KeyboardManager.ReadKey()).Key != ConsoleKeyEx.Enter) - { - if (current.Key == ConsoleKeyEx.NumEnter) break; - //Check for "special" keys - if (current.Key == ConsoleKeyEx.Backspace) // Backspace - { - if (currentCount > 0) - { - int curCharTemp = GetConsole().X; - chars.RemoveAt(currentCount - 1); - GetConsole().X = GetConsole().X - 1; - - //Move characters to the left - for (int x = currentCount - 1; x < chars.Count; x++) - { - Write(chars[x]); - } - - Write(' '); - - GetConsole().X = curCharTemp - 1; - - currentCount--; - } - continue; - } - else if (current.Key == ConsoleKeyEx.LeftArrow) - { - if (currentCount > 0) - { - GetConsole().X = GetConsole().X - 1; - currentCount--; - } - continue; - } - else if (current.Key == ConsoleKeyEx.RightArrow) - { - if (currentCount < chars.Count) - { - GetConsole().X = GetConsole().X + 1; - currentCount++; - } - continue; - } - - if (current.KeyChar == '\0') continue; - - //Write the character to the screen - if (currentCount == chars.Count) - { - chars.Add(current.KeyChar); - Write(current.KeyChar); - currentCount++; - } - else - { - //Insert the new character in the correct location - //For some reason, List.Insert() doesn't work properly - //so the character has to be inserted manually - List temp = new List(); - - for (int x = 0; x < chars.Count; x++) - { - if (x == currentCount) - { - temp.Add(current.KeyChar); - } - - temp.Add(chars[x]); - } - - chars = temp; - - //Shift the characters to the right - for (int x = currentCount; x < chars.Count; x++) - { - Write(chars[x]); - } - - GetConsole().X -= (chars.Count - currentCount) - 1; - currentCount++; - } - } - WriteLine(); - - char[] final = chars.ToArray(); - //if there's some process queued, we just set the first as the main and queue the otherones + } + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return null; + } + List chars = new List(32); + KeyEvent current; + int currentCount = 0; + + while ((current = KeyboardManager.ReadKey()).Key != ConsoleKeyEx.Enter) + { + if (current.Key == ConsoleKeyEx.NumEnter) break; + //Check for "special" keys + if (current.Key == ConsoleKeyEx.Backspace) // Backspace + { + if (currentCount > 0) + { + int curCharTemp = GetConsole().X; + chars.RemoveAt(currentCount - 1); + GetConsole().X = GetConsole().X - 1; + + //Move characters to the left + for (int x = currentCount - 1; x < chars.Count; x++) + { + Write(chars[x]); + } + + Write(' '); + + GetConsole().X = curCharTemp - 1; + + currentCount--; + } + continue; + } + else if (current.Key == ConsoleKeyEx.LeftArrow) + { + if (currentCount > 0) + { + GetConsole().X = GetConsole().X - 1; + currentCount--; + } + continue; + } + else if (current.Key == ConsoleKeyEx.RightArrow) + { + if (currentCount < chars.Count) + { + GetConsole().X = GetConsole().X + 1; + currentCount++; + } + continue; + } + + if (current.KeyChar == '\0') continue; + + //Write the character to the screen + if (currentCount == chars.Count) + { + chars.Add(current.KeyChar); + Write(current.KeyChar); + currentCount++; + } + else + { + //Insert the new character in the correct location + //For some reason, List.Insert() doesn't work properly + //so the character has to be inserted manually + List temp = new List(); + + for (int x = 0; x < chars.Count; x++) + { + if (x == currentCount) + { + temp.Add(current.KeyChar); + } + + temp.Add(chars[x]); + } + + chars = temp; + + //Shift the characters to the right + for (int x = currentCount; x < chars.Count; x++) + { + Write(chars[x]); + } + + GetConsole().X -= (chars.Count - currentCount) - 1; + currentCount++; + } + } + WriteLine(); + + char[] final = chars.ToArray(); + //if there's some process queued, we just set the first as the main and queue the otherones if (queue.Count > 0) { - Cosmos.HAL.Global.mDebugger.Send($"Dequeuing {queue[0].name} and locking console to it"); + Cosmos.HAL.Global.mDebugger.Send($"Removing {queue[0].name} from Queue and locking console to it"); LockContext = queue[0]; old = queue; queue = new List(); @@ -556,184 +550,184 @@ public static String ReadLine() if (context != LockContext) queue.Add(context); } - } - return new string(final); - } - - public static void ResetColor() - { - set_BackgroundColor(ConsoleColor.Black); - set_ForegroundColor(ConsoleColor.White); - } - - public static void SetBufferSize(int width, int height) - { - WriteLine("Not implemented: SetBufferSize"); - } - - public static void SetCursorPosition(int left, int top) - { - set_CursorLeft(left); - set_CursorTop(top); - } - - //public static void SetError(TextWriter newError) { - // WriteLine("Not implemented: SetError"); - //} - - //public static void SetIn(TextReader newIn) { - // WriteLine("Not implemented: SetIn"); - //} - - //public static void SetOut(TextWriter newOut) { - // WriteLine("Not implemented: SetOut"); - //} - - public static void SetWindowPosition(int left, int top) - { - WriteLine("Not implemented: SetWindowPosition"); - } - - public static void SetWindowSize(int width, int height) - { - WriteLine("Not implemented: SetWindowSize"); - } - - #region Write - - public static void Write(bool aBool) - { - Write(aBool.ToString()); - } - - /* - * A .Net character can be effectevily more can one byte so calling the low level Console.Write() will be wrong as - * it accepts only bytes, we need to convert it using the specified OutputEncoding but to do this we have to convert - * it ToString first - */ - public static void Write(char aChar) => Write(aChar.ToString()); - - public static void Write(char[] aBuffer) => Write(aBuffer, 0, aBuffer.Length); - - /* Decimal type is not working yet... */ - //public static void Write(decimal aDecimal) => Write(aDecimal.ToString()); - - public static void Write(double aDouble) => Write(aDouble.ToString()); - - public static void Write(float aFloat) => Write(aFloat.ToString()); - - public static void Write(int aInt) => Write(aInt.ToString()); - - public static void Write(long aLong) => Write(aLong.ToString()); - - /* Correct behaviour printing null should not throw NRE or do nothing but should print an empty string */ - public static void Write(object value) => Write((value ?? String.Empty)); - - public static void Write(string aText) - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - - byte[] aTextEncoded = ConsoleOutputEncoding.GetBytes(aText); - GetConsole().Write(aTextEncoded); - } - - public static void Write(uint aInt) => Write(aInt.ToString()); - - public static void Write(ulong aLong) => Write(aLong.ToString()); - - public static void Write(string format, object arg0) => Write(String.Format(format, arg0)); - - public static void Write(string format, object arg0, object arg1) => Write(String.Format(format, arg0, arg1)); - - public static void Write(string format, object arg0, object arg1, object arg2) => Write(String.Format(format, arg0, arg1, arg2)); - - public static void Write(string format, object arg0, object arg1, object arg2, object arg3) => Write(String.Format(format, arg0, arg1, arg2, arg3)); - - public static void Write(string format, params object[] arg) => Write(String.Format(format, arg)); - - public static void Write(char[] aBuffer, int aIndex, int aCount) - { - if (aBuffer == null) - { - throw new ArgumentNullException("aBuffer"); - } - if (aIndex < 0) - { - throw new ArgumentOutOfRangeException("aIndex"); - } - if (aCount < 0) - { - throw new ArgumentOutOfRangeException("aCount"); - } - if ((aBuffer.Length - aIndex) < aCount) - { - throw new ArgumentException(); - } - for (int i = 0; i < aCount; i++) - { - Write(aBuffer[aIndex + i]); - } - } - - //You'd expect this to be on System.Console wouldn't you? Well, it ain't so we just rely on Write(object value) - //public static void Write(byte aByte) { - // Write(aByte.ToString()); - //} - -#endregion - -#region WriteLine - - public static void WriteLine() => Write(Environment.NewLine); - - public static void WriteLine(bool aBool) => WriteLine(aBool.ToString()); - - public static void WriteLine(char aChar) => WriteLine(aChar.ToString()); - - public static void WriteLine(char[] aBuffer) => WriteLine(new String(aBuffer)); - - /* Decimal type is not working yet... */ - //public static void WriteLine(decimal aDecimal) => WriteLine(aDecimal.ToString()); - - public static void WriteLine(double aDouble) => WriteLine(aDouble.ToString()); - - public static void WriteLine(float aFloat) => WriteLine(aFloat.ToString()); - - public static void WriteLine(int aInt) => WriteLine(aInt.ToString()); - - public static void WriteLine(long aLong) => WriteLine(aLong.ToString()); - - /* Correct behaviour printing null should not throw NRE or do nothing but should print an empty line */ - public static void WriteLine(object value) => Write((value ?? String.Empty) + Environment.NewLine); - - public static void WriteLine(string aText) => Write(aText + Environment.NewLine); - - public static void WriteLine(uint aInt) => WriteLine(aInt.ToString()); - - public static void WriteLine(ulong aLong) => WriteLine(aLong.ToString()); - - public static void WriteLine(string format, object arg0) => WriteLine(String.Format(format, arg0)); - - public static void WriteLine(string format, object arg0, object arg1) => WriteLine(String.Format(format, arg0, arg1)); - - public static void WriteLine(string format, object arg0, object arg1, object arg2) => WriteLine(String.Format(format, arg0, arg1, arg2)); - - public static void WriteLine(string format, object arg0, object arg1, object arg2, object arg3) => WriteLine(String.Format(format, arg0, arg1, arg2, arg3)); - - public static void WriteLine(string format, params object[] arg) => WriteLine(String.Format(format, arg)); - - public static void WriteLine(char[] aBuffer, int aIndex, int aCount) - { - Write(aBuffer, aIndex, aCount); - WriteLine(); - } - -#endregion - - } -} + } + return new string(final); + } + + public static void ResetColor() + { + set_BackgroundColor(ConsoleColor.Black); + set_ForegroundColor(ConsoleColor.White); + } + + public static void SetBufferSize(int width, int height) + { + WriteLine("Not implemented: SetBufferSize"); + } + + public static void SetCursorPosition(int left, int top) + { + set_CursorLeft(left); + set_CursorTop(top); + } + + //public static void SetError(TextWriter newError) { + // WriteLine("Not implemented: SetError"); + //} + + //public static void SetIn(TextReader newIn) { + // WriteLine("Not implemented: SetIn"); + //} + + //public static void SetOut(TextWriter newOut) { + // WriteLine("Not implemented: SetOut"); + //} + + public static void SetWindowPosition(int left, int top) + { + WriteLine("Not implemented: SetWindowPosition"); + } + + public static void SetWindowSize(int width, int height) + { + WriteLine("Not implemented: SetWindowSize"); + } + + #region Write + + public static void Write(bool aBool) + { + Write(aBool.ToString()); + } + + /* + * A .Net character can be effectevily more can one byte so calling the low level Console.Write() will be wrong as + * it accepts only bytes, we need to convert it using the specified OutputEncoding but to do this we have to convert + * it ToString first + */ + public static void Write(char aChar) => Write(aChar.ToString()); + + public static void Write(char[] aBuffer) => Write(aBuffer, 0, aBuffer.Length); + + /* Decimal type is not working yet... */ + //public static void Write(decimal aDecimal) => Write(aDecimal.ToString()); + + public static void Write(double aDouble) => Write(aDouble.ToString()); + + public static void Write(float aFloat) => Write(aFloat.ToString()); + + public static void Write(int aInt) => Write(aInt.ToString()); + + public static void Write(long aLong) => Write(aLong.ToString()); + + /* Correct behaviour printing null should not throw NRE or do nothing but should print an empty string */ + public static void Write(object value) => Write((value ?? String.Empty)); + + public static void Write(string aText) + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + + byte[] aTextEncoded = ConsoleOutputEncoding.GetBytes(aText); + GetConsole().Write(aTextEncoded); + } + + public static void Write(uint aInt) => Write(aInt.ToString()); + + public static void Write(ulong aLong) => Write(aLong.ToString()); + + public static void Write(string format, object arg0) => Write(String.Format(format, arg0)); + + public static void Write(string format, object arg0, object arg1) => Write(String.Format(format, arg0, arg1)); + + public static void Write(string format, object arg0, object arg1, object arg2) => Write(String.Format(format, arg0, arg1, arg2)); + + public static void Write(string format, object arg0, object arg1, object arg2, object arg3) => Write(String.Format(format, arg0, arg1, arg2, arg3)); + + public static void Write(string format, params object[] arg) => Write(String.Format(format, arg)); + + public static void Write(char[] aBuffer, int aIndex, int aCount) + { + if (aBuffer == null) + { + throw new ArgumentNullException("aBuffer"); + } + if (aIndex < 0) + { + throw new ArgumentOutOfRangeException("aIndex"); + } + if (aCount < 0) + { + throw new ArgumentOutOfRangeException("aCount"); + } + if ((aBuffer.Length - aIndex) < aCount) + { + throw new ArgumentException(); + } + for (int i = 0; i < aCount; i++) + { + Write(aBuffer[aIndex + i]); + } + } + + //You'd expect this to be on System.Console wouldn't you? Well, it ain't so we just rely on Write(object value) + //public static void Write(byte aByte) { + // Write(aByte.ToString()); + //} + +#endregion + +#region WriteLine + + public static void WriteLine() => Write(Environment.NewLine); + + public static void WriteLine(bool aBool) => WriteLine(aBool.ToString()); + + public static void WriteLine(char aChar) => WriteLine(aChar.ToString()); + + public static void WriteLine(char[] aBuffer) => WriteLine(new String(aBuffer)); + + /* Decimal type is not working yet... */ + //public static void WriteLine(decimal aDecimal) => WriteLine(aDecimal.ToString()); + + public static void WriteLine(double aDouble) => WriteLine(aDouble.ToString()); + + public static void WriteLine(float aFloat) => WriteLine(aFloat.ToString()); + + public static void WriteLine(int aInt) => WriteLine(aInt.ToString()); + + public static void WriteLine(long aLong) => WriteLine(aLong.ToString()); + + /* Correct behaviour printing null should not throw NRE or do nothing but should print an empty line */ + public static void WriteLine(object value) => Write((value ?? String.Empty) + Environment.NewLine); + + public static void WriteLine(string aText) => Write(aText + Environment.NewLine); + + public static void WriteLine(uint aInt) => WriteLine(aInt.ToString()); + + public static void WriteLine(ulong aLong) => WriteLine(aLong.ToString()); + + public static void WriteLine(string format, object arg0) => WriteLine(String.Format(format, arg0)); + + public static void WriteLine(string format, object arg0, object arg1) => WriteLine(String.Format(format, arg0, arg1)); + + public static void WriteLine(string format, object arg0, object arg1, object arg2) => WriteLine(String.Format(format, arg0, arg1, arg2)); + + public static void WriteLine(string format, object arg0, object arg1, object arg2, object arg3) => WriteLine(String.Format(format, arg0, arg1, arg2, arg3)); + + public static void WriteLine(string format, params object[] arg) => WriteLine(String.Format(format, arg)); + + public static void WriteLine(char[] aBuffer, int aIndex, int aCount) + { + Write(aBuffer, aIndex, aCount); + WriteLine(); + } + +#endregion + + } +} From 64b2d3bd41b7ee2975b3f61262d53966558fa60e Mon Sep 17 00:00:00 2001 From: F4lc0131 Date: Tue, 5 Jan 2021 13:53:44 +0100 Subject: [PATCH 3/6] Add files via upload --- source/Cosmos.System2/LockSystem.cs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 source/Cosmos.System2/LockSystem.cs diff --git a/source/Cosmos.System2/LockSystem.cs b/source/Cosmos.System2/LockSystem.cs new file mode 100644 index 0000000000..b035991f8d --- /dev/null +++ b/source/Cosmos.System2/LockSystem.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cosmos.System +{ + public class LockSystem + { + public static Dictionary definedLocks = new Dictionary(); + public class Lock + { + internal Lock() { } + public Core.Processing.ProcessContext.Context LockContext = null; + public List queue = new List(); + } + public static Lock DefineLock(string LockName) + { + definedLocks.Add(LockName, new Lock()); + return definedLocks[LockName]; + } + } +} From 978eb419b240b0250a444e99223b27ad4927573d Mon Sep 17 00:00:00 2001 From: F4lc0131 Date: Tue, 5 Jan 2021 13:54:14 +0100 Subject: [PATCH 4/6] Add files via upload --- .../System/ConsoleImpl.cs | 1470 +++++++++-------- 1 file changed, 749 insertions(+), 721 deletions(-) diff --git a/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs b/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs index 8f9cf2ee93..a13cdb68dc 100644 --- a/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs +++ b/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs @@ -1,733 +1,761 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Cosmos.System; -using IL2CPU.API; -using IL2CPU.API.Attribs; - -namespace Cosmos.System_Plugs.System -{ - [Plug(Target = typeof (global::System.Console))] - public static class ConsoleImpl - { - private static ConsoleColor mForeground = ConsoleColor.White; - private static ConsoleColor mBackground = ConsoleColor.Black; - private static Encoding ConsoleInputEncoding = Encoding.ASCII; - private static Encoding ConsoleOutputEncoding = Encoding.ASCII; - - private static readonly Cosmos.System.Console mFallbackConsole = new Cosmos.System.Console(null); - - private static Cosmos.System.Console GetConsole() - { - return mFallbackConsole; - } - - public static ConsoleColor get_BackgroundColor() - { - return mBackground; - } - - public static void set_BackgroundColor(ConsoleColor value) - { - mBackground = value; - //Cosmos.HAL.Global.TextScreen.SetColors(mForeground, mBackground); - if (GetConsole() != null) GetConsole().Background = value; - } - - public static int get_BufferHeight() - { - WriteLine("Not implemented: get_BufferHeight"); - return -1; - } - - public static void set_BufferHeight(int aHeight) - { - WriteLine("Not implemented: set_BufferHeight"); - } - - public static int get_BufferWidth() - { - WriteLine("Not implemented: get_BufferWidth"); - return -1; - } - - public static void set_BufferWidth(int aWidth) - { - WriteLine("Not implemented: set_BufferWidth"); - } - - public static bool get_CapsLock() - { - return Global.CapsLock; - } - - public static int get_CursorLeft() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return 0; - } - return GetConsole().X; - } - - public static void set_CursorLeft(int x) - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - - if (x < get_WindowWidth()) - { - xConsole.X = x; - } - else - { - WriteLine("x must be lower than the console width!"); - } - } - - public static int get_CursorSize() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return 0; - } - return xConsole.CursorSize; - } - - public static void set_CursorSize(int aSize) - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - xConsole.CursorSize = aSize; - } - - public static int get_CursorTop() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return 0; - } - return GetConsole().Y; - } - - public static void set_CursorTop(int y) - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - - if (y < get_WindowHeight()) - { - xConsole.Y = y; - } - else - { - WriteLine("y must be lower than the console height!"); - } - } - - public static bool get_CursorVisible() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - return false; - } - return GetConsole().CursorVisible; - } - - public static void set_CursorVisible(bool value) - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - xConsole.CursorVisible = value; - } - - - //public static TextWriter get_Error() { - // WriteLine("Not implemented: get_Error"); - // return null; - //} - - public static ConsoleColor get_ForegroundColor() - { - return mForeground; - } - - public static void set_ForegroundColor(ConsoleColor value) - { - mForeground = value; - //Cosmos.HAL.Global.TextScreen.SetColors(mForeground, mBackground); - if (GetConsole() != null) GetConsole().Foreground = value; - } - - //public static TextReader get_In() - //{ - // WriteLine("Not implemented: get_In"); - // return null; - //} - - public static Encoding get_InputEncoding() - { - return ConsoleInputEncoding; - } - - public static void set_InputEncoding(Encoding value) - { - ConsoleInputEncoding = value; - } - - public static Encoding get_OutputEncoding() - { - return ConsoleOutputEncoding; - } - - - public static void set_OutputEncoding(Encoding value) - { - ConsoleOutputEncoding = value; - } - - public static bool get_KeyAvailable() - { - return KeyboardManager.KeyAvailable; - } - - public static int get_LargestWindowHeight() - { - WriteLine("Not implemented: get_LargestWindowHeight"); - return -1; - } - - public static int get_LargestWindowWidth() - { - WriteLine("Not implemented: get_LargestWindowWidth"); - return -1; - } - - public static bool get_NumberLock() - { - return Global.NumLock; - } - - //public static TextWriter get_Out() { - // WriteLine("Not implemented: get_Out"); - // return null; - //} - - public static string get_Title() - { - WriteLine("Not implemented: get_Title"); - return string.Empty; - } - - public static void set_Title(string value) - { - WriteLine("Not implemented: set_Title"); - } - - public static bool get_TreatControlCAsInput() - { - WriteLine("Not implemented: get_TreatControlCAsInput"); - return false; - } - - public static void set_TreatControlCAsInput(bool value) - { - WriteLine("Not implemented: set_TreatControlCAsInput"); - } - - public static int get_WindowHeight() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return 25; - } - return GetConsole().Rows; - } - - public static void set_WindowHeight(int value) - { - WriteLine("Not implemented: set_WindowHeight"); - } - - public static int get_WindowLeft() - { - WriteLine("Not implemented: get_WindowLeft"); - return -1; - } - - public static void set_WindowLeft(int value) - { - WriteLine("Not implemented: set_WindowLeft"); - } - - public static int get_WindowTop() - { - WriteLine("Not implemented: get_WindowTop"); - return -1; - } - - public static void set_WindowTop(int value) - { - WriteLine("Not implemented: set_WindowTop"); - } - - public static int get_WindowWidth() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return 85; - } - return GetConsole().Cols; - } - - public static void set_WindowWidth(int value) - { - WriteLine("Not implemented: set_WindowWidth"); - } - - /// - /// The ArgumentOutOfRangeException check is now done at driver level in PCSpeaker - is it still needed here? - /// - /// - /// - public static void Beep(int aFrequency, int aDuration) - { - if (aFrequency < 37 || aFrequency > 32767) - { - throw new ArgumentOutOfRangeException("Frequency must be between 37 and 32767Hz"); - } - - if (aDuration <= 0) - { - throw new ArgumentOutOfRangeException("Duration must be more than 0"); - } - - PCSpeaker.Beep((uint) aFrequency, (uint) aDuration); - } - - /// - /// Beep() is pure CIL - /// Default implementation beeps for 200 milliseconds at 800 hertz - /// In Cosmos, these are Cosmos.System.Duration.Default and Cosmos.System.Notes.Default respectively, - /// and are used when there are no params - /// https://docs.microsoft.com/en-us/dotnet/api/system.console.beep?view=netcore-2.0 - /// - public static void Beep() - { - PCSpeaker.Beep(); - } - - //TODO: Console uses TextWriter - intercept and plug it instead - public static void Clear() - { - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; - } - GetConsole().Clear(); - } - - // MoveBufferArea(int, int, int, int, int, int) is pure CIL - - public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, - int targetLeft, int targetTop, Char sourceChar, ConsoleColor sourceForeColor, ConsoleColor sourceBackColor) - { - WriteLine("Not implemented: MoveBufferArea"); - } - - //public static Stream OpenStandardError() { - // WriteLine("Not implemented: OpenStandardError"); - //} - - //public static Stream OpenStandardError(int bufferSize) { - // WriteLine("Not implemented: OpenStandardError"); - //} - - //public static Stream OpenStandardInput(int bufferSize) { - // WriteLine("Not implemented: OpenStandardInput"); - //} - - //public static Stream OpenStandardInput() { - // WriteLine("Not implemented: OpenStandardInput"); - //} - - //public static Stream OpenStandardOutput(int bufferSize) { - // WriteLine("Not implemented: OpenStandardOutput"); - //} - - //public static Stream OpenStandardOutput() { - // WriteLine("Not implemented: OpenStandardOutput"); - //} - - public static int Read() - { - // TODO special cases, if needed, that returns -1 - KeyEvent xResult; - - if (KeyboardManager.TryReadKey(out xResult)) - { - return xResult.KeyChar; - } - else - { - return -1; - } - } - - public static ConsoleKeyInfo ReadKey() - { - return ReadKey(false); - } - - // ReadKey() pure CIL - - public static ConsoleKeyInfo ReadKey(bool intercept) - { - var key = KeyboardManager.ReadKey(); - if (intercept == false && key.KeyChar != '\0') - { - Write(key.KeyChar); - } - - //TODO: Plug HasFlag and use the next 3 lines instead of the 3 following lines - - //bool xShift = key.Modifiers.HasFlag(ConsoleModifiers.Shift); - //bool xAlt = key.Modifiers.HasFlag(ConsoleModifiers.Alt); - //bool xControl = key.Modifiers.HasFlag(ConsoleModifiers.Control); - - bool xShift = (key.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift; - bool xAlt = (key.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt; - bool xControl = (key.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control; - - return new ConsoleKeyInfo(key.KeyChar, key.Key.ToConsoleKey(), xShift, xAlt, xControl); - } - - private static Core.Processing.ProcessContext.Context LockContext = null; - private static List queue = new List(); +using System; +using System.Collections.Generic; +using System.Text; +using Cosmos.System; +using IL2CPU.API; +using IL2CPU.API.Attribs; + +namespace Cosmos.System_Plugs.System +{ + [Plug(Target = typeof (global::System.Console))] + public static class ConsoleImpl + { + private static ConsoleColor mForeground = ConsoleColor.White; + private static ConsoleColor mBackground = ConsoleColor.Black; + private static Encoding ConsoleInputEncoding = Encoding.ASCII; + private static Encoding ConsoleOutputEncoding = Encoding.ASCII; + + private static readonly Cosmos.System.Console mFallbackConsole = new Cosmos.System.Console(null); + + private static Cosmos.System.Console GetConsole() + { + return mFallbackConsole; + } + + public static ConsoleColor get_BackgroundColor() + { + return mBackground; + } + + public static void set_BackgroundColor(ConsoleColor value) + { + mBackground = value; + //Cosmos.HAL.Global.TextScreen.SetColors(mForeground, mBackground); + if (GetConsole() != null) GetConsole().Background = value; + } + + public static int get_BufferHeight() + { + WriteLine("Not implemented: get_BufferHeight"); + return -1; + } + + public static void set_BufferHeight(int aHeight) + { + WriteLine("Not implemented: set_BufferHeight"); + } + + public static int get_BufferWidth() + { + WriteLine("Not implemented: get_BufferWidth"); + return -1; + } + + public static void set_BufferWidth(int aWidth) + { + WriteLine("Not implemented: set_BufferWidth"); + } + + public static bool get_CapsLock() + { + return Global.CapsLock; + } + + public static int get_CursorLeft() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return 0; + } + return GetConsole().X; + } + + public static void set_CursorLeft(int x) + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + + if (x < get_WindowWidth()) + { + xConsole.X = x; + } + else + { + WriteLine("x must be lower than the console width!"); + } + } + + public static int get_CursorSize() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return 0; + } + return xConsole.CursorSize; + } + + public static void set_CursorSize(int aSize) + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + xConsole.CursorSize = aSize; + } + + public static int get_CursorTop() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return 0; + } + return GetConsole().Y; + } + + public static void set_CursorTop(int y) + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + + if (y < get_WindowHeight()) + { + xConsole.Y = y; + } + else + { + WriteLine("y must be lower than the console height!"); + } + } + + public static bool get_CursorVisible() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + return false; + } + return GetConsole().CursorVisible; + } + + public static void set_CursorVisible(bool value) + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + xConsole.CursorVisible = value; + } + + + //public static TextWriter get_Error() { + // WriteLine("Not implemented: get_Error"); + // return null; + //} + + public static ConsoleColor get_ForegroundColor() + { + return mForeground; + } + + public static void set_ForegroundColor(ConsoleColor value) + { + mForeground = value; + //Cosmos.HAL.Global.TextScreen.SetColors(mForeground, mBackground); + if (GetConsole() != null) GetConsole().Foreground = value; + } + + //public static TextReader get_In() + //{ + // WriteLine("Not implemented: get_In"); + // return null; + //} + + public static Encoding get_InputEncoding() + { + return ConsoleInputEncoding; + } + + public static void set_InputEncoding(Encoding value) + { + ConsoleInputEncoding = value; + } + + public static Encoding get_OutputEncoding() + { + return ConsoleOutputEncoding; + } + + + public static void set_OutputEncoding(Encoding value) + { + ConsoleOutputEncoding = value; + } + + public static bool get_KeyAvailable() + { + return KeyboardManager.KeyAvailable; + } + + public static int get_LargestWindowHeight() + { + WriteLine("Not implemented: get_LargestWindowHeight"); + return -1; + } + + public static int get_LargestWindowWidth() + { + WriteLine("Not implemented: get_LargestWindowWidth"); + return -1; + } + + public static bool get_NumberLock() + { + return Global.NumLock; + } + + //public static TextWriter get_Out() { + // WriteLine("Not implemented: get_Out"); + // return null; + //} + + public static string get_Title() + { + WriteLine("Not implemented: get_Title"); + return string.Empty; + } + + public static void set_Title(string value) + { + WriteLine("Not implemented: set_Title"); + } + + public static bool get_TreatControlCAsInput() + { + WriteLine("Not implemented: get_TreatControlCAsInput"); + return false; + } + + public static void set_TreatControlCAsInput(bool value) + { + WriteLine("Not implemented: set_TreatControlCAsInput"); + } + + public static int get_WindowHeight() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return 25; + } + return GetConsole().Rows; + } + + public static void set_WindowHeight(int value) + { + WriteLine("Not implemented: set_WindowHeight"); + } + + public static int get_WindowLeft() + { + WriteLine("Not implemented: get_WindowLeft"); + return -1; + } + + public static void set_WindowLeft(int value) + { + WriteLine("Not implemented: set_WindowLeft"); + } + + public static int get_WindowTop() + { + WriteLine("Not implemented: get_WindowTop"); + return -1; + } + + public static void set_WindowTop(int value) + { + WriteLine("Not implemented: set_WindowTop"); + } + + public static int get_WindowWidth() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return 85; + } + return GetConsole().Cols; + } + + public static void set_WindowWidth(int value) + { + WriteLine("Not implemented: set_WindowWidth"); + } + + /// + /// The ArgumentOutOfRangeException check is now done at driver level in PCSpeaker - is it still needed here? + /// + /// + /// + public static void Beep(int aFrequency, int aDuration) + { + if (aFrequency < 37 || aFrequency > 32767) + { + throw new ArgumentOutOfRangeException("Frequency must be between 37 and 32767Hz"); + } + + if (aDuration <= 0) + { + throw new ArgumentOutOfRangeException("Duration must be more than 0"); + } + + PCSpeaker.Beep((uint) aFrequency, (uint) aDuration); + } + + /// + /// Beep() is pure CIL + /// Default implementation beeps for 200 milliseconds at 800 hertz + /// In Cosmos, these are Cosmos.System.Duration.Default and Cosmos.System.Notes.Default respectively, + /// and are used when there are no params + /// https://docs.microsoft.com/en-us/dotnet/api/system.console.beep?view=netcore-2.0 + /// + public static void Beep() + { + PCSpeaker.Beep(); + } + + //TODO: Console uses TextWriter - intercept and plug it instead + public static void Clear() + { + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + GetConsole().Clear(); + } + + // MoveBufferArea(int, int, int, int, int, int) is pure CIL + + public static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, + int targetLeft, int targetTop, Char sourceChar, ConsoleColor sourceForeColor, ConsoleColor sourceBackColor) + { + WriteLine("Not implemented: MoveBufferArea"); + } + + //public static Stream OpenStandardError() { + // WriteLine("Not implemented: OpenStandardError"); + //} + + //public static Stream OpenStandardError(int bufferSize) { + // WriteLine("Not implemented: OpenStandardError"); + //} + + //public static Stream OpenStandardInput(int bufferSize) { + // WriteLine("Not implemented: OpenStandardInput"); + //} + + //public static Stream OpenStandardInput() { + // WriteLine("Not implemented: OpenStandardInput"); + //} + + //public static Stream OpenStandardOutput(int bufferSize) { + // WriteLine("Not implemented: OpenStandardOutput"); + //} + + //public static Stream OpenStandardOutput() { + // WriteLine("Not implemented: OpenStandardOutput"); + //} + + public static int Read() + { + // TODO special cases, if needed, that returns -1 + KeyEvent xResult; + + if (KeyboardManager.TryReadKey(out xResult)) + { + return xResult.KeyChar; + } + else + { + return -1; + } + } + + public static ConsoleKeyInfo ReadKey() + { + return ReadKey(false); + } + + // ReadKey() pure CIL + + public static ConsoleKeyInfo ReadKey(bool intercept) + { + var key = KeyboardManager.ReadKey(); + if (intercept == false && key.KeyChar != '\0') + { + Write(key.KeyChar); + } + + //TODO: Plug HasFlag and use the next 3 lines instead of the 3 following lines + + //bool xShift = key.Modifiers.HasFlag(ConsoleModifiers.Shift); + //bool xAlt = key.Modifiers.HasFlag(ConsoleModifiers.Alt); + //bool xControl = key.Modifiers.HasFlag(ConsoleModifiers.Control); + + bool xShift = (key.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift; + bool xAlt = (key.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt; + bool xControl = (key.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control; + + return new ConsoleKeyInfo(key.KeyChar, key.Key.ToConsoleKey(), xShift, xAlt, xControl); + } + + private static LockSystem.Lock _lock = LockSystem.DefineLock("Console"); + private static List chars = new List(32); + private static List old = null; - public static String ReadLine() - { - if (LockContext == null) LockContext = Core.Processing.ProcessContext.m_CurrentContext; //if nobody locked the Console, just lock it - else if (LockContext != Core.Processing.ProcessContext.m_CurrentContext) - { - queue.Add(Core.Processing.ProcessContext.m_CurrentContext); - while (LockContext != Core.Processing.ProcessContext.m_CurrentContext) ; - } - var xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return null; - } - List chars = new List(32); - KeyEvent current; - int currentCount = 0; - - while ((current = KeyboardManager.ReadKey()).Key != ConsoleKeyEx.Enter) + public static String ReadLine() + { + if (_lock.LockContext == null) _lock.LockContext = Core.Processing.ProcessContext.m_CurrentContext; //if nobody locked the Console, just lock it + else if (_lock.LockContext != Core.Processing.ProcessContext.m_CurrentContext) { - if (current.Key == ConsoleKeyEx.NumEnter) break; - //Check for "special" keys - if (current.Key == ConsoleKeyEx.Backspace) // Backspace - { - if (currentCount > 0) - { - int curCharTemp = GetConsole().X; - chars.RemoveAt(currentCount - 1); - GetConsole().X = GetConsole().X - 1; - - //Move characters to the left - for (int x = currentCount - 1; x < chars.Count; x++) - { - Write(chars[x]); - } - - Write(' '); - - GetConsole().X = curCharTemp - 1; - - currentCount--; - } - continue; - } - else if (current.Key == ConsoleKeyEx.LeftArrow) - { - if (currentCount > 0) - { - GetConsole().X = GetConsole().X - 1; - currentCount--; - } - continue; - } - else if (current.Key == ConsoleKeyEx.RightArrow) - { - if (currentCount < chars.Count) - { - GetConsole().X = GetConsole().X + 1; - currentCount++; - } - continue; - } - - if (current.KeyChar == '\0') continue; - - //Write the character to the screen - if (currentCount == chars.Count) - { - chars.Add(current.KeyChar); - Write(current.KeyChar); - currentCount++; - } - else - { - //Insert the new character in the correct location - //For some reason, List.Insert() doesn't work properly - //so the character has to be inserted manually - List temp = new List(); - - for (int x = 0; x < chars.Count; x++) - { - if (x == currentCount) - { - temp.Add(current.KeyChar); - } - - temp.Add(chars[x]); - } - - chars = temp; - - //Shift the characters to the right - for (int x = currentCount; x < chars.Count; x++) - { - Write(chars[x]); - } - - GetConsole().X -= (chars.Count - currentCount) - 1; - currentCount++; - } + _lock.queue.Add(Core.Processing.ProcessContext.m_CurrentContext); + while (_lock.LockContext != Core.Processing.ProcessContext.m_CurrentContext) ; } + LockSystem.definedLocks["Console"] = _lock; + chars = new List(32); + var xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return null; + } + KeyEvent current; + int currentCount = 0; + + while ((current = KeyboardManager.ReadKey()).Key != ConsoleKeyEx.Enter) + { + if (current.Key == ConsoleKeyEx.NumEnter) break; + //Check for "special" keys + if (current.Key == ConsoleKeyEx.Backspace) // Backspace + { + if (currentCount > 0) + { + int curCharTemp = GetConsole().X; + chars.RemoveAt(currentCount - 1); + GetConsole().X = GetConsole().X - 1; + + //Move characters to the left + for (int x = currentCount - 1; x < chars.Count; x++) + { + Write(chars[x]); + } + + Write(' '); + + GetConsole().X = curCharTemp - 1; + + currentCount--; + } + continue; + } + else if (current.Key == ConsoleKeyEx.LeftArrow) + { + if (currentCount > 0) + { + GetConsole().X = GetConsole().X - 1; + currentCount--; + } + continue; + } + else if (current.Key == ConsoleKeyEx.RightArrow) + { + if (currentCount < chars.Count) + { + GetConsole().X = GetConsole().X + 1; + currentCount++; + } + continue; + } + + if (current.KeyChar == '\0') continue; + + //Write the character to the screen + if (currentCount == chars.Count) + { + chars.Add(current.KeyChar); + Write(current.KeyChar); + currentCount++; + } + else + { + //Insert the new character in the correct location + //For some reason, List.Insert() doesn't work properly + //so the character has to be inserted manually + List temp = new List(); + + for (int x = 0; x < chars.Count; x++) + { + if (x == currentCount) + { + temp.Add(current.KeyChar); + } + + temp.Add(chars[x]); + } + + chars = temp; + + //Shift the characters to the right + for (int x = currentCount; x < chars.Count; x++) + { + Write(chars[x]); + } + + GetConsole().X -= (chars.Count - currentCount) - 1; + currentCount++; + } + } WriteLine(); - char[] final = chars.ToArray(); - //if there's some process queued, we just set the first as the main and queue the otherones - if (queue.Count > 0) + while (_lock.LockContext != Core.Processing.ProcessContext.m_CurrentContext) ; //let's wait until we go back to the lock thread + + char[] final = chars.ToArray(); + //if there's some process queued, we just set the first as the main and queue the other ones + if (_lock.queue.Count > 0) { - Cosmos.HAL.Global.mDebugger.Send($"Removing {queue[0].name} from Queue and locking console to it"); - LockContext = queue[0]; - old = queue; - queue = new List(); + HAL.Global.mDebugger.Send($"Removing {_lock.queue[0].name} from Queue and locking console to it"); + _lock.LockContext = _lock.queue[0]; + old = _lock.queue; + _lock.queue = new List(); foreach (Core.Processing.ProcessContext.Context context in old) { - if (context != LockContext) - queue.Add(context); + if (context != _lock.LockContext) + _lock.queue.Add(context); } - } - return new string(final); - } - - public static void ResetColor() - { - set_BackgroundColor(ConsoleColor.Black); - set_ForegroundColor(ConsoleColor.White); - } - - public static void SetBufferSize(int width, int height) - { - WriteLine("Not implemented: SetBufferSize"); - } - - public static void SetCursorPosition(int left, int top) - { - set_CursorLeft(left); - set_CursorTop(top); - } - - //public static void SetError(TextWriter newError) { - // WriteLine("Not implemented: SetError"); - //} - - //public static void SetIn(TextReader newIn) { - // WriteLine("Not implemented: SetIn"); - //} - - //public static void SetOut(TextWriter newOut) { - // WriteLine("Not implemented: SetOut"); - //} - - public static void SetWindowPosition(int left, int top) - { - WriteLine("Not implemented: SetWindowPosition"); - } - - public static void SetWindowSize(int width, int height) - { - WriteLine("Not implemented: SetWindowSize"); - } - - #region Write - - public static void Write(bool aBool) - { - Write(aBool.ToString()); - } - - /* - * A .Net character can be effectevily more can one byte so calling the low level Console.Write() will be wrong as - * it accepts only bytes, we need to convert it using the specified OutputEncoding but to do this we have to convert - * it ToString first - */ - public static void Write(char aChar) => Write(aChar.ToString()); - - public static void Write(char[] aBuffer) => Write(aBuffer, 0, aBuffer.Length); - - /* Decimal type is not working yet... */ - //public static void Write(decimal aDecimal) => Write(aDecimal.ToString()); - - public static void Write(double aDouble) => Write(aDouble.ToString()); - - public static void Write(float aFloat) => Write(aFloat.ToString()); - - public static void Write(int aInt) => Write(aInt.ToString()); - - public static void Write(long aLong) => Write(aLong.ToString()); - - /* Correct behaviour printing null should not throw NRE or do nothing but should print an empty string */ - public static void Write(object value) => Write((value ?? String.Empty)); - - public static void Write(string aText) - { - var xConsole = GetConsole(); - if (xConsole == null) + } + return new string(final); + } + + public static void ResetColor() + { + set_BackgroundColor(ConsoleColor.Black); + set_ForegroundColor(ConsoleColor.White); + } + + public static void SetBufferSize(int width, int height) + { + WriteLine("Not implemented: SetBufferSize"); + } + + public static void SetCursorPosition(int left, int top) + { + set_CursorLeft(left); + set_CursorTop(top); + } + + //public static void SetError(TextWriter newError) { + // WriteLine("Not implemented: SetError"); + //} + + //public static void SetIn(TextReader newIn) { + // WriteLine("Not implemented: SetIn"); + //} + + //public static void SetOut(TextWriter newOut) { + // WriteLine("Not implemented: SetOut"); + //} + + public static void SetWindowPosition(int left, int top) + { + WriteLine("Not implemented: SetWindowPosition"); + } + + public static void SetWindowSize(int width, int height) + { + WriteLine("Not implemented: SetWindowSize"); + } + + #region Write + + public static void Write(bool aBool) + { + Write(aBool.ToString()); + } + + /* + * A .Net character can be effectevily more can one byte so calling the low level Console.Write() will be wrong as + * it accepts only bytes, we need to convert it using the specified OutputEncoding but to do this we have to convert + * it ToString first + */ + public static void Write(char aChar) => Write(aChar.ToString()); + + public static void Write(char[] aBuffer) => Write(aBuffer, 0, aBuffer.Length); + + /* Decimal type is not working yet... */ + //public static void Write(decimal aDecimal) => Write(aDecimal.ToString()); + + public static void Write(double aDouble) => Write(aDouble.ToString()); + + public static void Write(float aFloat) => Write(aFloat.ToString()); + + public static void Write(int aInt) => Write(aInt.ToString()); + + public static void Write(long aLong) => Write(aLong.ToString()); + + /* Correct behaviour printing null should not throw NRE or do nothing but should print an empty string */ + public static void Write(object value) => Write((value ?? String.Empty)); + + private static Cosmos.System.Console xConsole = null; + + private static List WOld = null; + private static LockSystem.Lock _Wlock = LockSystem.DefineLock("Console.Write"); + public static void Write(string aText) + { + if (_Wlock.LockContext == null) _Wlock.LockContext = Core.Processing.ProcessContext.m_CurrentContext; //if nobody locked the Console, just lock it + else if (_Wlock.LockContext != Core.Processing.ProcessContext.m_CurrentContext) { - // for now: - return; + _Wlock.queue.Add(Core.Processing.ProcessContext.m_CurrentContext); + while (_Wlock.LockContext != Core.Processing.ProcessContext.m_CurrentContext) ; } - - byte[] aTextEncoded = ConsoleOutputEncoding.GetBytes(aText); - GetConsole().Write(aTextEncoded); - } - - public static void Write(uint aInt) => Write(aInt.ToString()); - - public static void Write(ulong aLong) => Write(aLong.ToString()); - - public static void Write(string format, object arg0) => Write(String.Format(format, arg0)); - - public static void Write(string format, object arg0, object arg1) => Write(String.Format(format, arg0, arg1)); - - public static void Write(string format, object arg0, object arg1, object arg2) => Write(String.Format(format, arg0, arg1, arg2)); - - public static void Write(string format, object arg0, object arg1, object arg2, object arg3) => Write(String.Format(format, arg0, arg1, arg2, arg3)); - - public static void Write(string format, params object[] arg) => Write(String.Format(format, arg)); - - public static void Write(char[] aBuffer, int aIndex, int aCount) - { - if (aBuffer == null) + LockSystem.definedLocks["Console"] = _Wlock; + xConsole = GetConsole(); + if (xConsole == null) + { + // for now: + return; + } + + byte[] aTextEncoded = ConsoleOutputEncoding.GetBytes(aText); + GetConsole().Write(aTextEncoded); + //if there's some process queued, we just set the first as the main and queue the other ones + if (_Wlock.queue.Count > 0) { - throw new ArgumentNullException("aBuffer"); - } - if (aIndex < 0) - { - throw new ArgumentOutOfRangeException("aIndex"); - } - if (aCount < 0) - { - throw new ArgumentOutOfRangeException("aCount"); - } - if ((aBuffer.Length - aIndex) < aCount) - { - throw new ArgumentException(); - } - for (int i = 0; i < aCount; i++) - { - Write(aBuffer[aIndex + i]); - } - } - - //You'd expect this to be on System.Console wouldn't you? Well, it ain't so we just rely on Write(object value) - //public static void Write(byte aByte) { - // Write(aByte.ToString()); - //} - -#endregion - -#region WriteLine - - public static void WriteLine() => Write(Environment.NewLine); - - public static void WriteLine(bool aBool) => WriteLine(aBool.ToString()); - - public static void WriteLine(char aChar) => WriteLine(aChar.ToString()); - - public static void WriteLine(char[] aBuffer) => WriteLine(new String(aBuffer)); - - /* Decimal type is not working yet... */ - //public static void WriteLine(decimal aDecimal) => WriteLine(aDecimal.ToString()); - - public static void WriteLine(double aDouble) => WriteLine(aDouble.ToString()); - - public static void WriteLine(float aFloat) => WriteLine(aFloat.ToString()); - - public static void WriteLine(int aInt) => WriteLine(aInt.ToString()); - - public static void WriteLine(long aLong) => WriteLine(aLong.ToString()); - - /* Correct behaviour printing null should not throw NRE or do nothing but should print an empty line */ - public static void WriteLine(object value) => Write((value ?? String.Empty) + Environment.NewLine); - - public static void WriteLine(string aText) => Write(aText + Environment.NewLine); - - public static void WriteLine(uint aInt) => WriteLine(aInt.ToString()); - - public static void WriteLine(ulong aLong) => WriteLine(aLong.ToString()); - - public static void WriteLine(string format, object arg0) => WriteLine(String.Format(format, arg0)); - - public static void WriteLine(string format, object arg0, object arg1) => WriteLine(String.Format(format, arg0, arg1)); - - public static void WriteLine(string format, object arg0, object arg1, object arg2) => WriteLine(String.Format(format, arg0, arg1, arg2)); - - public static void WriteLine(string format, object arg0, object arg1, object arg2, object arg3) => WriteLine(String.Format(format, arg0, arg1, arg2, arg3)); - - public static void WriteLine(string format, params object[] arg) => WriteLine(String.Format(format, arg)); - - public static void WriteLine(char[] aBuffer, int aIndex, int aCount) - { - Write(aBuffer, aIndex, aCount); - WriteLine(); - } - -#endregion - - } -} + HAL.Global.mDebugger.Send($"Removing {_Wlock.queue[0].name} from Queue and locking console to it"); + _Wlock.LockContext = _Wlock.queue[0]; + WOld = _Wlock.queue; + _Wlock.queue = new List(); + foreach (Core.Processing.ProcessContext.Context context in WOld) + { + if (context != _Wlock.LockContext) + _Wlock.queue.Add(context); + } + } + } + + public static void Write(uint aInt) => Write(aInt.ToString()); + + public static void Write(ulong aLong) => Write(aLong.ToString()); + + public static void Write(string format, object arg0) => Write(String.Format(format, arg0)); + + public static void Write(string format, object arg0, object arg1) => Write(String.Format(format, arg0, arg1)); + + public static void Write(string format, object arg0, object arg1, object arg2) => Write(String.Format(format, arg0, arg1, arg2)); + + public static void Write(string format, object arg0, object arg1, object arg2, object arg3) => Write(String.Format(format, arg0, arg1, arg2, arg3)); + + public static void Write(string format, params object[] arg) => Write(String.Format(format, arg)); + + public static void Write(char[] aBuffer, int aIndex, int aCount) + { + if (aBuffer == null) + { + throw new ArgumentNullException("aBuffer"); + } + if (aIndex < 0) + { + throw new ArgumentOutOfRangeException("aIndex"); + } + if (aCount < 0) + { + throw new ArgumentOutOfRangeException("aCount"); + } + if ((aBuffer.Length - aIndex) < aCount) + { + throw new ArgumentException(); + } + for (int i = 0; i < aCount; i++) + { + Write(aBuffer[aIndex + i]); + } + } + + //You'd expect this to be on System.Console wouldn't you? Well, it ain't so we just rely on Write(object value) + //public static void Write(byte aByte) { + // Write(aByte.ToString()); + //} + +#endregion + +#region WriteLine + + public static void WriteLine() => Write(Environment.NewLine); + + public static void WriteLine(bool aBool) => WriteLine(aBool.ToString()); + + public static void WriteLine(char aChar) => WriteLine(aChar.ToString()); + + public static void WriteLine(char[] aBuffer) => WriteLine(new String(aBuffer)); + + /* Decimal type is not working yet... */ + //public static void WriteLine(decimal aDecimal) => WriteLine(aDecimal.ToString()); + + public static void WriteLine(double aDouble) => WriteLine(aDouble.ToString()); + + public static void WriteLine(float aFloat) => WriteLine(aFloat.ToString()); + + public static void WriteLine(int aInt) => WriteLine(aInt.ToString()); + + public static void WriteLine(long aLong) => WriteLine(aLong.ToString()); + + /* Correct behaviour printing null should not throw NRE or do nothing but should print an empty line */ + public static void WriteLine(object value) => Write((value ?? String.Empty) + Environment.NewLine); + + public static void WriteLine(string aText) => Write(aText + Environment.NewLine); + + public static void WriteLine(uint aInt) => WriteLine(aInt.ToString()); + + public static void WriteLine(ulong aLong) => WriteLine(aLong.ToString()); + + public static void WriteLine(string format, object arg0) => WriteLine(String.Format(format, arg0)); + + public static void WriteLine(string format, object arg0, object arg1) => WriteLine(String.Format(format, arg0, arg1)); + + public static void WriteLine(string format, object arg0, object arg1, object arg2) => WriteLine(String.Format(format, arg0, arg1, arg2)); + + public static void WriteLine(string format, object arg0, object arg1, object arg2, object arg3) => WriteLine(String.Format(format, arg0, arg1, arg2, arg3)); + + public static void WriteLine(string format, params object[] arg) => WriteLine(String.Format(format, arg)); + + public static void WriteLine(char[] aBuffer, int aIndex, int aCount) + { + Write(aBuffer, aIndex, aCount); + WriteLine(); + } + +#endregion + + } +} From 5d7732fafaf2b457e5ad7a4152fb83b1aff7ab9a Mon Sep 17 00:00:00 2001 From: F4lc0131 Date: Wed, 6 Jan 2021 01:32:18 +0100 Subject: [PATCH 5/6] Adapting to Mutex class as suggested Removing LockSystem that we don't need anymore --- source/Cosmos.System2/LockSystem.cs | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 source/Cosmos.System2/LockSystem.cs diff --git a/source/Cosmos.System2/LockSystem.cs b/source/Cosmos.System2/LockSystem.cs deleted file mode 100644 index b035991f8d..0000000000 --- a/source/Cosmos.System2/LockSystem.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cosmos.System -{ - public class LockSystem - { - public static Dictionary definedLocks = new Dictionary(); - public class Lock - { - internal Lock() { } - public Core.Processing.ProcessContext.Context LockContext = null; - public List queue = new List(); - } - public static Lock DefineLock(string LockName) - { - definedLocks.Add(LockName, new Lock()); - return definedLocks[LockName]; - } - } -} From 5184a701b839113c8173555d36fe65ca67cd2b90 Mon Sep 17 00:00:00 2001 From: F4lc0131 Date: Wed, 6 Jan 2021 01:33:34 +0100 Subject: [PATCH 6/6] Adapting to Mutex class as suggested Modifying Console.ReadLine and Write to use Mutex instead of LockSystem --- .../System/ConsoleImpl.cs | 71 +++++-------------- 1 file changed, 16 insertions(+), 55 deletions(-) diff --git a/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs b/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs index a13cdb68dc..a36a0e6c06 100644 --- a/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs +++ b/source/Cosmos.System2_Plugs/System/ConsoleImpl.cs @@ -13,7 +13,9 @@ public static class ConsoleImpl private static ConsoleColor mForeground = ConsoleColor.White; private static ConsoleColor mBackground = ConsoleColor.Black; private static Encoding ConsoleInputEncoding = Encoding.ASCII; - private static Encoding ConsoleOutputEncoding = Encoding.ASCII; + private static Encoding ConsoleOutputEncoding = Encoding.ASCII; + private static Core.Processing.Mutex mConsoleGateRead = new Core.Processing.Mutex(); + private static Core.Processing.Mutex mConsoleGateWrite = new Core.Processing.Mutex(); private static readonly Cosmos.System.Console mFallbackConsole = new Cosmos.System.Console(null); @@ -429,21 +431,13 @@ public static ConsoleKeyInfo ReadKey(bool intercept) bool xControl = (key.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control; return new ConsoleKeyInfo(key.KeyChar, key.Key.ToConsoleKey(), xShift, xAlt, xControl); - } - - private static LockSystem.Lock _lock = LockSystem.DefineLock("Console"); - private static List chars = new List(32); - - private static List old = null; + } + + private static List chars = new List(32); public static String ReadLine() { - if (_lock.LockContext == null) _lock.LockContext = Core.Processing.ProcessContext.m_CurrentContext; //if nobody locked the Console, just lock it - else if (_lock.LockContext != Core.Processing.ProcessContext.m_CurrentContext) - { - _lock.queue.Add(Core.Processing.ProcessContext.m_CurrentContext); - while (_lock.LockContext != Core.Processing.ProcessContext.m_CurrentContext) ; - } - LockSystem.definedLocks["Console"] = _lock; + if (mConsoleGateRead != null) + mConsoleGateRead.Lock(); chars = new List(32); var xConsole = GetConsole(); if (xConsole == null) @@ -537,24 +531,11 @@ public static String ReadLine() currentCount++; } } - WriteLine(); - - while (_lock.LockContext != Core.Processing.ProcessContext.m_CurrentContext) ; //let's wait until we go back to the lock thread + WriteLine(); char[] final = chars.ToArray(); - //if there's some process queued, we just set the first as the main and queue the other ones - if (_lock.queue.Count > 0) - { - HAL.Global.mDebugger.Send($"Removing {_lock.queue[0].name} from Queue and locking console to it"); - _lock.LockContext = _lock.queue[0]; - old = _lock.queue; - _lock.queue = new List(); - foreach (Core.Processing.ProcessContext.Context context in old) - { - if (context != _lock.LockContext) - _lock.queue.Add(context); - } - } + if (mConsoleGateRead != null) + mConsoleGateRead.Unlock(); return new string(final); } @@ -628,39 +609,19 @@ public static void Write(bool aBool) public static void Write(object value) => Write((value ?? String.Empty)); private static Cosmos.System.Console xConsole = null; - - private static List WOld = null; - private static LockSystem.Lock _Wlock = LockSystem.DefineLock("Console.Write"); + public static void Write(string aText) { - if (_Wlock.LockContext == null) _Wlock.LockContext = Core.Processing.ProcessContext.m_CurrentContext; //if nobody locked the Console, just lock it - else if (_Wlock.LockContext != Core.Processing.ProcessContext.m_CurrentContext) + if (mConsoleGateWrite != null) { - _Wlock.queue.Add(Core.Processing.ProcessContext.m_CurrentContext); - while (_Wlock.LockContext != Core.Processing.ProcessContext.m_CurrentContext) ; - } - LockSystem.definedLocks["Console"] = _Wlock; - xConsole = GetConsole(); - if (xConsole == null) - { - // for now: - return; + mConsoleGateWrite.Lock(); } - byte[] aTextEncoded = ConsoleOutputEncoding.GetBytes(aText); GetConsole().Write(aTextEncoded); //if there's some process queued, we just set the first as the main and queue the other ones - if (_Wlock.queue.Count > 0) + if (mConsoleGateWrite != null) { - HAL.Global.mDebugger.Send($"Removing {_Wlock.queue[0].name} from Queue and locking console to it"); - _Wlock.LockContext = _Wlock.queue[0]; - WOld = _Wlock.queue; - _Wlock.queue = new List(); - foreach (Core.Processing.ProcessContext.Context context in WOld) - { - if (context != _Wlock.LockContext) - _Wlock.queue.Add(context); - } + mConsoleGateWrite.Unlock(); } }