cc-haxe/src/bin/Terminal.hx

166 lines
3.4 KiB
Haxe
Raw Normal View History

package bin;
2023-04-13 22:19:49 +00:00
import kernel.ps.Process;
import kernel.ps.ProcessManager;
import kernel.ps.ProcessHandle;
2023-01-28 02:55:32 +00:00
import lib.ui.UIApp;
2022-12-19 20:06:23 +00:00
import lib.Color;
import kernel.ui.WindowContext;
import kernel.ui.WindowManager;
2023-01-28 02:55:32 +00:00
using tink.CoreApi;
class Terminal extends UIApp {
private var context:WindowContext;
private var input:String = "";
2022-12-19 16:35:52 +00:00
private var backlog:Array<String> = [];
2023-01-28 02:55:32 +00:00
private var exitTrigger: Bool -> Void;
public function new() {}
2023-01-28 02:55:32 +00:00
public function invoke(context: WindowContext): Future<Bool> {
this.context = context;
this.context.onChar.handle(char -> {
this.input += char;
this.redrawInput();
});
this.context.onKey.handle(e -> {
if (e.keyCode == 259) {
this.input = this.input.substr(0, this.input.length - 1);
this.redrawInput();
} else if (e.keyCode == 257) {
this.backlog.push("> " + this.input);
var command = this.input;
this.input = "";
this.redrawBacklog();
this.redrawInput();
this.invokeCommand(command);
}
});
WindowManager.instance.focusContextToOutput(context, "main");
this.redrawInput();
2023-01-28 02:55:32 +00:00
return new Future<Bool>(cb -> {
this.exitTrigger = cb;
return null;
});
}
private function redrawBacklog() {
var size = this.context.getSize();
var linesAvailable = size.y - 1;
var start:Int = this.backlog.length - linesAvailable;
2022-12-19 16:35:52 +00:00
for (i in 0...linesAvailable) {
var line = this.backlog[start + i];
this.context.setCursorPos(0, i);
this.context.clearLine();
if (line != null) {
this.context.write(line);
}
}
this.moveCursorToInput();
}
private function redrawInput() {
var size = this.context.getSize();
this.context.setCursorPos(0, size.y - 1);
this.context.clearLine();
this.context.setTextColor(Color.Blue);
this.context.write("> ");
this.context.setTextColor(Color.White);
this.context.write(this.input);
this.context.setCursorBlink(true);
}
2022-12-19 16:35:52 +00:00
private function invokeCommand(command:String):Void {
var args = this.parseArgs(command);
if (args.length == 0) {
return;
}
var commandName = args[0];
// Handle built-in commands
switch (commandName) {
case "clear":
this.clear();
return;
}
var commandArgs:Array<String> = args.slice(1);
var hadInput = false;
2023-04-13 22:19:49 +00:00
var ps = getProgByName(commandName);
if (ps == null) {
this.backlog.push("Unknown command: " + commandName);
this.redrawBacklog();
this.redrawInput();
return;
}
ProcessManager.run(ps,{
args: commandArgs,
onWrite: (s:String) -> {
if (!hadInput) {
this.backlog.push("");
hadInput = true;
}
this.backlog[this.backlog.length - 1] += s;
this.redrawBacklog();
},
2023-04-13 22:19:49 +00:00
onExit: (success:Bool) -> {
if (this.backlog[this.backlog.length - 1] == "") {
this.backlog.pop();
}
this.redrawInput();
}
});
this.context.setCursorBlink(false);
}
2022-12-19 16:35:52 +00:00
private function parseArgs(command:String):Array<String> {
// TODO: tim and quote handling
return command.split(" ");
}
private function clear() {
this.backlog = [];
this.redrawBacklog();
}
2023-04-13 22:19:49 +00:00
private function getProgByName(name:String):Process {
switch (name) {
case "hello":
return new HelloWorld();
2022-12-17 14:08:07 +00:00
case "net":
return new Net();
2022-12-19 22:28:46 +00:00
case "rs":
return new Redstone();
2023-01-27 13:34:25 +00:00
case "disk":
return new Disk();
2023-03-27 22:57:04 +00:00
case "gps":
return new GPS();
default:
return null;
}
}
private function moveCursorToInput() {
var size = this.context.getSize();
this.context.setCursorPos(this.input.length + 2, size.y - 1);
}
}