Reorganize project structure

This commit is contained in:
Stone_Red
2026-06-19 00:56:46 +02:00
parent 6f58eefb66
commit 95d88f1a8d
84 changed files with 267 additions and 186 deletions
+117
View File
@@ -0,0 +1,117 @@
using RemSox.Kernel.Processing;
using RemSox.Kernel.UI.CLI;
namespace RemSox.Kernel.Processes;
internal class CliProcess() : Process("Cli")
{
private string currentInput = string.Empty;
private int historyIndex = -1;
private bool commandRunning = false;
private CancellationTokenSource? commandCancellationTokenSource = null;
internal override void Start(string[] args)
{
Console.Clear();
Console.WriteLine("Welcome RemSox!");
Console.WriteLine("Type 'help' to see available commands.");
Console.WriteLine(Environment.ProcessorCount + " CPU cores detected");
Console.Write("> ");
historyIndex = CommandManager.GetCommandHistory().Count;
}
internal override async void Tick()
{
while (Console.KeyAvailable)
{
ConsoleKeyInfo key = Console.ReadKey(intercept: true);
if (commandRunning)
{
if (key.Key == ConsoleKey.C && key.Modifiers.HasFlag(ConsoleModifiers.Control) && commandCancellationTokenSource is not null)
{
await commandCancellationTokenSource.CancelAsync();
}
continue;
}
switch (key.Key)
{
case ConsoleKey.Enter:
Console.WriteLine();
await HandleCommand(currentInput);
historyIndex = CommandManager.GetCommandHistory().Count;
currentInput = string.Empty;
Console.Write("> ");
break;
case ConsoleKey.Backspace:
if (currentInput.Length > 0)
{
currentInput = currentInput[..^1];
Console.Write("\b \b");
}
break;
case ConsoleKey.UpArrow:
if (CommandManager.GetCommandHistory().Count > 0)
{
historyIndex = Math.Max(historyIndex - 1, 0);
currentInput = CommandManager.GetCommandHistory()[historyIndex];
Console.Write("\r> " + currentInput + new string(' ', Console.WindowWidth - currentInput.Length - 2));
Console.CursorLeft = 0;
Console.CursorTop--;
Console.Write("> " + currentInput);
}
break;
case ConsoleKey.DownArrow:
if (CommandManager.GetCommandHistory().Count > 0)
{
historyIndex = Math.Min(historyIndex + 1, CommandManager.GetCommandHistory().Count - 1);
currentInput = CommandManager.GetCommandHistory()[historyIndex];
Console.Write("\r> " + currentInput + new string(' ', Console.WindowWidth - currentInput.Length - 2));
Console.CursorLeft = 0;
Console.CursorTop--;
Console.Write("> " + currentInput);
}
break;
default:
if (!char.IsControl(key.KeyChar))
{
currentInput += key.KeyChar;
Console.Write(key.KeyChar);
}
break;
}
}
}
private async Task HandleCommand(string input)
{
if (string.IsNullOrWhiteSpace(input))
{
return;
}
commandCancellationTokenSource = new CancellationTokenSource();
commandRunning = true;
bool handled = await CommandManager.TryExecuteAsync(input, Console.WriteLine, commandCancellationTokenSource.Token);
if (!handled)
{
Console.WriteLine($"\"{input}\" is not a command");
}
commandRunning = false;
commandCancellationTokenSource.Dispose();
commandCancellationTokenSource = null;
}
}
+271
View File
@@ -0,0 +1,271 @@
using RemSox.Kernel.UI.GUI.Rendering;
using Cosmos.Kernel.System.Graphics;
using Cosmos.Kernel.System.Keyboard;
using Cosmos.Kernel.System.Mouse;
using RemSox.Kernel.Processing;
using RemSox.Shared.UI;
using RemSox.Kernel.UI.GUI.Layout;
using RemSox.Shared.UI.GUI.Rendering;
using RemSox.Kernel.UI.GUI.UIEelements.Controls;
using RemSox.Kernel.UI.GUI.Windows;
using System.Drawing;
namespace RemSox.Kernel.Processes;
internal class DesktopProcess() : Process("Desktop Manager")
{
private static bool isGraphicsInitialized = false;
private static readonly (string Name, Func<int> Spawn)[] AvailableApps = [
("Terminal", () => ProcessManager.SpawnProcess<TerminalProcess>()),
("Test Process",() => ProcessManager.SpawnProcess<TestProcess>()),
("YesNt", () => ProcessManager.SpawnProcess<YesNtInterpreterProcess>()),
];
private Window taskbar = null!;
private Window? startMenu;
private Button startButton = null!;
private readonly List<(int WindowId, Button Button)> windowButtons = [];
private int tickCount;
internal override void Start(string[] args)
{
if (!isGraphicsInitialized)
{
WindowManager.AddRenderSource(new CanvasRenderSource());
isGraphicsInitialized = true;
}
WindowManager.InvalidateAll();
CreateTaskbar();
}
private void CreateTaskbar()
{
Canvas canvas = FullScreenCanvas.GetFullScreenCanvas();
int screenW = (int)canvas.Mode.Width;
int screenH = (int)canvas.Mode.Height;
const int taskbarH = 36;
taskbar = WindowManager.CreateWindow(this, "Taskbar",
new Size(screenW, taskbarH),
new Point(0, screenH - taskbarH));
taskbar.HasChrome = false;
taskbar.IsResizable = false;
taskbar.IsDraggable = false;
taskbar.ZIndex = int.MaxValue;
taskbar.AutoFlush = true;
startButton = taskbar.CreateUIElement<Button>(b =>
{
b.Position = new Point(2, 2);
b.Size = new Size(65, taskbarH - 4);
b.Text = "Start";
b.BackgroundColor = Color.FromArgb(0, 100, 180);
b.TextColor = Color.White;
});
startButton.OnClick += (_, _) => ToggleStartMenu();
}
private void ToggleStartMenu()
{
if (startMenu is not null)
{
WindowManager.CloseWindow(startMenu);
startMenu = null;
return;
}
Canvas canvas = FullScreenCanvas.GetFullScreenCanvas();
int screenH = (int)canvas.Mode.Height;
int menuW = 150;
int itemH = 22;
int menuH = (AvailableApps.Length * itemH) + 10;
int menuX = 2;
int menuY = screenH - 36 - menuH;
startMenu = WindowManager.CreateWindow(this, "Start Menu",
new Size(menuW, menuH),
new Point(menuX, menuY));
startMenu.HasChrome = false;
startMenu.IsResizable = false;
startMenu.IsDraggable = false;
startMenu.ZIndex = int.MaxValue - 1;
startMenu.AutoFlush = true;
StackLayout stack = startMenu.CreateStackLayout(5, 5, 2);
stack.UniformWidth = menuW - 10;
foreach ((string? name, Func<int>? spawn) in AvailableApps)
{
Button appBtn = stack.Add<Button>(b =>
{
b.Size = new Size(menuW - 10, itemH);
b.Text = name;
b.BackgroundColor = Color.FromArgb(60, 60, 65);
b.TextColor = Color.White;
});
appBtn.OnClick += (_, _) =>
{
_ = spawn();
WindowManager.CloseWindow(startMenu);
startMenu = null;
};
}
}
private Point lastLocalMousePos = Point.Empty;
private bool lastLocalLeft, lastLocalRight, lastLocalMiddle;
internal override void Tick()
{
PollLocalHardware();
WindowManager.Update();
if (tickCount % 5 == 0)
{
UpdateWindowButtons();
}
tickCount++;
if (!ProcessManager.IsProcessRunning<TerminalProcess>())
{
_ = ProcessManager.SpawnProcess<TerminalProcess>();
}
}
private void PollLocalHardware()
{
Point pos = new(MouseManager.X, MouseManager.Y);
if (pos != lastLocalMousePos)
{
WindowManager.EnqueueMouseEvent(MouseEvent.Move(pos.X, pos.Y));
lastLocalMousePos = pos;
}
bool left = MouseManager.LeftButton;
if (left != lastLocalLeft)
{
WindowManager.EnqueueMouseEvent(left
? MouseEvent.ButtonDown(pos.X, pos.Y, MouseButton.Left)
: MouseEvent.ButtonUp(pos.X, pos.Y, MouseButton.Left));
lastLocalLeft = left;
}
bool right = MouseManager.RightButton;
if (right != lastLocalRight)
{
WindowManager.EnqueueMouseEvent(right
? MouseEvent.ButtonDown(pos.X, pos.Y, MouseButton.Right)
: MouseEvent.ButtonUp(pos.X, pos.Y, MouseButton.Right));
lastLocalRight = right;
}
bool middle = MouseManager.MiddleButton;
if (middle != lastLocalMiddle)
{
WindowManager.EnqueueMouseEvent(middle
? MouseEvent.ButtonDown(pos.X, pos.Y, MouseButton.Middle)
: MouseEvent.ButtonUp(pos.X, pos.Y, MouseButton.Middle));
lastLocalMiddle = middle;
}
int scroll = MouseManager.ScrollDelta;
if (scroll != 0)
{
WindowManager.EnqueueMouseEvent(MouseEvent.Wheel(pos.X, pos.Y, scroll));
}
while (KeyboardManager.TryReadKey(out KeyEvent? keyEvent) && keyEvent is not null)
{
WindowManager.EnqueueKeyEvent(keyEvent);
}
}
private void UpdateWindowButtons()
{
List<Window> allWindows = WindowManager.GetAllWindows()
.Where(w => w != taskbar && w != startMenu && w.HasChrome)
.ToList();
// Build lookup of current window IDs
HashSet<int> currentIds = [];
foreach (Window w in allWindows)
{
_ = currentIds.Add(w.Id);
}
// Remove buttons for windows that no longer exist
for (int i = windowButtons.Count - 1; i >= 0; i--)
{
(int winId, Button btn) = windowButtons[i];
if (!currentIds.Contains(winId))
{
taskbar.RemoveUIElement(btn.Id);
windowButtons.RemoveAt(i);
}
}
// Build lookup of existing tracked windows
Dictionary<int, Button> tracked = [];
foreach ((int winId, Button? btn) in windowButtons)
{
tracked[winId] = btn;
}
// Add new buttons and reposition everything in one pass
int btnX = startButton.Size.Width + 6;
windowButtons.Clear();
foreach (Window win in allWindows)
{
if (tracked.TryGetValue(win.Id, out Button? existing))
{
// Reposition existing button
existing.Position = new Point(btnX, 2);
}
else
{
// Create new button
existing = taskbar.CreateUIElement<Button>(b =>
{
b.Position = new Point(btnX, 2);
b.Size = new Size(100, 32);
b.Text = TruncateTitle(win.Title, 12);
b.BackgroundColor = Color.FromArgb(55, 55, 60);
b.TextColor = Color.White;
});
int capturedId = win.Id;
existing.OnClick += (_, _) =>
{
Window? target = WindowManager.GetAllWindows().FirstOrDefault(w => w.Id == capturedId);
if (target is not null)
{
WindowManager.FocusWindow(target);
}
};
}
// Update highlight for focused window
existing.BackgroundColor = win.IsFocused
? Color.FromArgb(0, 90, 160)
: Color.FromArgb(55, 55, 60);
windowButtons.Add((win.Id, existing));
btnX += 104;
}
}
private static string TruncateTitle(string title, int maxLen)
{
return title.Length <= maxLen ? title : title[..(maxLen - 1)] + "\u2026";
}
}
@@ -0,0 +1,221 @@
using Cosmos.Kernel.System.Graphics;
using Cosmos.Kernel.System.Keyboard;
using RemSox.Shared.Networking;
using RemSox.Kernel.Processing;
using RemSox.Shared.UI;
using RemSox.Shared.UI.GUI.Rendering;
using RemSox.Kernel.UI.GUI.Rendering;
using RemSox.Kernel.UI.GUI.Windows;
using System.Text;
namespace RemSox.Kernel.Processes;
internal sealed class RemoteDesktopProcess() : Process("Remote Desktop Server")
{
private TcpRpcServer? server;
private NetworkRenderSource? networkSource;
private CancellationTokenSource? cts;
public int Port { get; private set; }
internal override void Start(string[] args)
{
if (args.Length == 0 || !int.TryParse(args[0], out int port) || port <= 0 || port > 65535)
{
Logger.Log("Invalid port. Usage: rdp-start <port> (1-65535)", Logging.LogSeverity.Error);
RequestStop();
return;
}
Port = port;
cts = new CancellationTokenSource();
server = new TcpRpcServer();
networkSource = new NetworkRenderSource(server);
server.ListenTo("SyncRequest", async _ =>
{
Canvas canvas = FullScreenCanvas.GetFullScreenCanvas();
RenderCommand screenInfo = new()
{
Type = RenderCommandType.ScreenInfo,
WindowId = 0,
ElementId = 0,
Properties = new()
{
["Width"] = (int)canvas.Mode.Width,
["Height"] = (int)canvas.Mode.Height,
},
};
networkSource?.Render([screenInfo]);
WindowManager.InvalidateAll();
});
RegisterInputHandlers();
_ = Task.Run(() => server.StartAsync(port, cts.Token));
WindowManager.AddRenderSource(networkSource);
Logger.Log($"Remote desktop server started on port {port}.", Logging.LogSeverity.Info);
}
internal override void Tick()
{
}
internal override void Stop()
{
cts?.Cancel();
server?.Stop();
if (networkSource is not null)
{
WindowManager.RemoveRenderSource(networkSource);
}
Logger.Log("Remote desktop server stopped.", Logging.LogSeverity.Info);
}
private void RegisterInputHandlers()
{
if (server is null)
{
return;
}
server.ListenTo("MouseMove", async (payload) =>
{
(int X, int Y) = DeserializeMouseMove(payload);
WindowManager.EnqueueMouseEvent(MouseEvent.Move(X, Y));
});
server.ListenTo("MouseDown", async (payload) =>
{
(int X, int Y, string Button) = DeserializeMouseButton(payload);
WindowManager.EnqueueMouseEvent(MouseEvent.ButtonDown(X, Y, ParseButton(Button)));
});
server.ListenTo("MouseUp", async (payload) =>
{
(int X, int Y, string Button) = DeserializeMouseButton(payload);
WindowManager.EnqueueMouseEvent(MouseEvent.ButtonUp(X, Y, ParseButton(Button)));
});
server.ListenTo("MouseWheel", async (payload) =>
{
(int X, int Y, int Delta) = DeserializeMouseWheel(payload);
WindowManager.EnqueueMouseEvent(MouseEvent.Wheel(X, Y, Delta));
});
server.ListenTo("KeyEvent", async (payload) =>
{
(int Key, string KeyChar, bool Shift, bool Alt, bool Control, bool Pressed) = DeserializeKeyEvent(payload);
ConsoleKeyEx key = (ConsoleKeyEx)Key;
char keyChar = KeyChar.Length > 0 ? KeyChar[0] : '\0';
KeyEvent keyEvent = new(keyChar, key, Shift, Alt, Control, Pressed ? KeyEvent.KeyEventType.Make : KeyEvent.KeyEventType.Break);
WindowManager.EnqueueKeyEvent(keyEvent);
});
}
private static MouseButton ParseButton(string button)
{
return button switch
{
"Left" => MouseButton.Left,
"Right" => MouseButton.Right,
"Middle" => MouseButton.Middle,
_ => MouseButton.None
};
}
private static byte[] SerializeMouseMove(int x, int y)
{
byte[] data = new byte[8];
WriteInt32(data, 0, x);
WriteInt32(data, 4, y);
return data;
}
private static (int X, int Y) DeserializeMouseMove(byte[] data)
{
return (ReadInt32(data, 0), ReadInt32(data, 4));
}
private static byte[] SerializeMouseButton(int x, int y, string button)
{
byte[] buttonBytes = Encoding.UTF8.GetBytes(button);
byte[] data = new byte[8 + 4 + buttonBytes.Length];
WriteInt32(data, 0, x);
WriteInt32(data, 4, y);
WriteInt32(data, 8, buttonBytes.Length);
buttonBytes.CopyTo(data, 12);
return data;
}
private static (int X, int Y, string Button) DeserializeMouseButton(byte[] data)
{
int x = ReadInt32(data, 0);
int y = ReadInt32(data, 4);
int len = ReadInt32(data, 8);
string button = Encoding.UTF8.GetString(data, 12, len);
return (x, y, button);
}
private static byte[] SerializeMouseWheel(int x, int y, int delta)
{
byte[] data = new byte[12];
WriteInt32(data, 0, x);
WriteInt32(data, 4, y);
WriteInt32(data, 8, delta);
return data;
}
private static (int X, int Y, int Delta) DeserializeMouseWheel(byte[] data)
{
return (ReadInt32(data, 0), ReadInt32(data, 4), ReadInt32(data, 8));
}
private static byte[] SerializeKeyEvent(int key, string keyChar, bool shift, bool alt, bool control, bool pressed)
{
byte[] charBytes = Encoding.UTF8.GetBytes(keyChar);
byte[] data = new byte[4 + 4 + charBytes.Length + 4];
WriteInt32(data, 0, key);
WriteInt32(data, 4, charBytes.Length);
charBytes.CopyTo(data, 8);
int offset = 8 + charBytes.Length;
data[offset++] = shift ? (byte)1 : (byte)0;
data[offset++] = alt ? (byte)1 : (byte)0;
data[offset++] = control ? (byte)1 : (byte)0;
data[offset] = pressed ? (byte)1 : (byte)0;
return data;
}
private static (int Key, string KeyChar, bool Shift, bool Alt, bool Control, bool Pressed) DeserializeKeyEvent(byte[] data)
{
int key = ReadInt32(data, 0);
int charLen = ReadInt32(data, 4);
string keyChar = Encoding.UTF8.GetString(data, 8, charLen);
int offset = 8 + charLen;
bool shift = data[offset] != 0;
bool alt = data[offset + 1] != 0;
bool control = data[offset + 2] != 0;
bool pressed = data[offset + 3] != 0;
return (key, keyChar, shift, alt, control, pressed);
}
private static void WriteInt32(byte[] data, int offset, int value)
{
data[offset] = (byte)(value & 0xFF);
data[offset + 1] = (byte)((value >> 8) & 0xFF);
data[offset + 2] = (byte)((value >> 16) & 0xFF);
data[offset + 3] = (byte)((value >> 24) & 0xFF);
}
private static int ReadInt32(byte[] data, int offset)
{
return data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24);
}
}
+210
View File
@@ -0,0 +1,210 @@
using Cosmos.Kernel.System.Keyboard;
using RemSox.Kernel.Processing;
using RemSox.Kernel.UI.CLI;
using RemSox.Kernel.UI.GUI.UIEelements.Shapes;
using RemSox.Kernel.UI.GUI.Windows;
using System.Drawing;
namespace RemSox.Kernel.Processes;
public class TerminalProcess() : Process("Terminal")
{
private Window window = null!;
private readonly List<string> history = [];
private int historyIndex = -1;
private bool commandRunning = false;
private CancellationTokenSource? commandCancellationTokenSource = null;
private string currentInput = "";
private readonly List<Text> textLines = [];
private readonly Lock textLinesLock = new();
private const int LineHeight = 30;
private Size lastSize = new(-1, -1);
internal override void Start(string[] args)
{
window = CreateWindow("Terminal", new Size(400, 300));
PrintLine("RemSox GUI Terminal v1.0");
PrintLine("Type 'help' for commands.");
historyIndex = CommandManager.GetCommandHistory().Count;
window.Flush();
window.OnKeyEvent += HandleKey;
}
internal override void Tick()
{
if (window.Size != lastSize && !window.IsResizing)
{
lastSize = window.Size;
UpdateDisplay();
}
}
internal override void Stop()
{
window.OnKeyEvent -= HandleKey;
}
private async void HandleKey(KeyEvent keyEvent)
{
if (commandRunning)
{
if (keyEvent.Key == ConsoleKeyEx.C && keyEvent.Modifiers.HasFlag(ConsoleModifiers.Control) && commandCancellationTokenSource is not null)
{
await commandCancellationTokenSource.CancelAsync();
}
return;
}
if (keyEvent.Key == ConsoleKeyEx.Enter)
{
string cmd = currentInput;
PrintLine("> " + cmd);
currentInput = "";
if (!string.IsNullOrWhiteSpace(cmd))
{
if (cmd.Trim() == "exit")
{
RequestStop();
}
else if (cmd.Trim() == "clear")
{
lock (textLinesLock)
{
history.Clear();
UpdateDisplay();
}
}
else
{
commandCancellationTokenSource = new CancellationTokenSource();
commandRunning = true;
bool handled = await CommandManager.TryExecuteAsync(cmd, PrintLine, commandCancellationTokenSource.Token);
if (!handled)
{
PrintLine($"\"{cmd}\" is not a command");
}
commandRunning = false;
commandCancellationTokenSource.Dispose();
commandCancellationTokenSource = null;
}
historyIndex = CommandManager.GetCommandHistory().Count;
}
UpdateDisplay();
}
else if (keyEvent.Key == ConsoleKeyEx.Backspace)
{
if (currentInput.Length > 0)
{
currentInput = currentInput[..^1];
UpdateDisplay();
}
}
else if (keyEvent.Key == ConsoleKeyEx.UpArrow)
{
if (CommandManager.GetCommandHistory().Count > 0)
{
historyIndex = Math.Max(historyIndex - 1, 0);
currentInput = CommandManager.GetCommandHistory()[historyIndex];
UpdateDisplay();
}
}
else if (keyEvent.Key == ConsoleKeyEx.DownArrow)
{
if (CommandManager.GetCommandHistory().Count > 0)
{
historyIndex = Math.Min(historyIndex + 1, CommandManager.GetCommandHistory().Count - 1);
currentInput = CommandManager.GetCommandHistory()[historyIndex];
UpdateDisplay();
}
}
else if (!char.IsControl(keyEvent.KeyChar))
{
currentInput += keyEvent.KeyChar;
UpdateDisplay();
}
}
private void PrintLine(string text)
{
history.Add(text);
if (history.Count > 1000)
{
history.RemoveAt(0);
}
UpdateDisplay();
}
private void UpdateDisplay()
{
if (window is null)
{
return;
}
int availableHeight = window.Size.Height - 24; // 18 for title + 6 margin
int maxLines = (availableHeight / LineHeight) - 1; // -1 for input line
if (maxLines < 1)
{
maxLines = 1;
}
lock (textLinesLock)
{
// Ensure we have enough Text elements for maxLines + 1 (input line)
while (textLines.Count <= maxLines)
{
Text textElement = window.CreateUIElement<Text>(t =>
{
t.Color = Color.LightGreen;
t.Content = "";
t.FontSize = LineHeight;
});
textLines.Add(textElement);
}
// Calculate starting Y to align everything flush to the bottom margin
int startY = window.Size.Height - ((maxLines + 1) * LineHeight) - 5;
if (startY < 20)
{
startY = 20;
}
for (int i = 0; i < maxLines; i++)
{
int historyIndex = history.Count - maxLines + i;
string content = "";
if (historyIndex >= 0 && historyIndex < history.Count)
{
content = history[historyIndex];
}
textLines[i].Content = content;
textLines[i].Position = new Point(5, startY + (i * LineHeight));
}
// The last line is the input line
textLines[maxLines].Content = "> " + currentInput + "_";
textLines[maxLines].Position = new Point(5, startY + (maxLines * LineHeight));
// Hide any extra text lines we don't need
for (int i = maxLines + 1; i < textLines.Count; i++)
{
textLines[i].Content = "";
}
}
window.Flush();
}
}
+46
View File
@@ -0,0 +1,46 @@
using RemSox.Kernel.Processing;
using RemSox.Kernel.Processing.IPC;
using RemSox.Kernel.UI.GUI.UIEelements.Shapes;
using RemSox.Kernel.UI.GUI.Windows;
using System.Drawing;
namespace RemSox.Kernel.Processes;
public class TestProcess() : Process("Test Process")
{
internal override void Start(string[] args)
{
Window window = WindowManager.CreateWindow(this, "Test Window", new Size(200, 150));
window.AutoFlush = true;
Circle circle = window.CreateUIElement<Circle>(rect =>
{
rect.Position = new Point(10, 10);
rect.Radius = 50;
rect.Color = Color.Red;
});
circle.Radius = 40;
SendMessageToAllProcesses(new TestMessage { SenderProcessId = Id });
}
internal override void Tick()
{
// Example tick logic - could be used for animations, timed events, etc.
}
internal override void HandleInterProcessMessage(Message message)
{
if (message is TestMessage testMessage && message.SenderProcessId != Id)
{
Console.WriteLine($"Received message in {Name} (ID: {Id}): {testMessage.MessageText}");
}
}
}
internal class TestMessage : Message
{
public string MessageText { get; set; } = "Hello from TestMessage!";
}
@@ -0,0 +1,46 @@
using RemSox.Kernel.Processing;
using RemSox.Kernel.Utils;
using YesNt.Interpreter.Runtime;
namespace RemSox.Kernel.Processes;
public class YesNtInterpreterProcess() : Process("YesNtInterpreter")
{
private YesNtInterpreter interpreter = null!;
internal override void Start(string[] args)
{
// TODO: eventually we want to load these from a file instead of hardcoding them here
args = [
"win_create \"Test\" 320 240",
"global winId = %win_last_id",
"win_flush ${winId}",
"print ${winId}",
"label test:",
"goto test"
];
interpreter = new();
new YesNtWindowStatements(this).Register(interpreter);
interpreter.Prepare([.. args]);
}
internal override void Tick()
{
if (interpreter.IsRunning)
{
_ = interpreter.Step();
}
else
{
RequestStop();
}
}
internal override void Stop()
{
interpreter.Stop();
}
}