migrated the apps to processes

This commit is contained in:
Djeeberjr 2023-04-14 00:19:49 +02:00
parent 747bde4aa6
commit bd3402fc39
8 changed files with 149 additions and 203 deletions

View File

@ -1,19 +1,18 @@
package bin; package bin;
import kernel.ps.ProcessHandle;
import kernel.ps.Process;
import kernel.peripherals.Peripherals.Peripheral; import kernel.peripherals.Peripherals.Peripheral;
import lib.cli.TermHandle;
import lib.cli.CLIApp;
using tink.CoreApi; using tink.CoreApi;
using Lambda; using Lambda;
class Disk extends CLIApp { class Disk implements Process {
private var handle:ProcessHandle;
private var handle:TermHandle;
public function new() {} public function new() {}
public function invoke(handle:TermHandle):Future<Bool> { public function run(handle:ProcessHandle):Void {
this.handle = handle; this.handle = handle;
var subcommand = handle.args[0]; var subcommand = handle.args[0];
var driveAddr:Null<String> = handle.args[1]; var driveAddr:Null<String> = handle.args[1];
@ -27,12 +26,12 @@ class Disk extends CLIApp {
if (drive.isDiskPresent()){ if (drive.isDiskPresent()){
if (drive.hasAudio()){ if (drive.hasAudio()){
handle.writeLn('${addr} => ${label} [AUDIO]'); handle.writeLine('${addr} => ${label} [AUDIO]');
}else{ }else{
handle.writeLn('${addr} => ${label} (${id})'); handle.writeLine('${addr} => ${label} (${id})');
} }
}else { }else {
handle.writeLn('${addr} => [NO DISK]'); handle.writeLine('${addr} => [NO DISK]');
} }
return true; return true;
@ -41,18 +40,15 @@ class Disk extends CLIApp {
var drive = Peripheral.instance.getDrive(driveAddr); var drive = Peripheral.instance.getDrive(driveAddr);
if (drive == null){ if (drive == null){
handle.writeLn("Drive not found: " + driveAddr); handle.writeLine("Drive not found: " + driveAddr);
return Future.sync(false);
} }
if (!drive.isDiskPresent()){ if (!drive.isDiskPresent()){
handle.writeLn("No disk in drive: " + driveAddr); handle.writeLine("No disk in drive: " + driveAddr);
return Future.sync(false);
} }
if (!drive.hasAudio()){ if (!drive.hasAudio()){
handle.writeLn("Disk in drive " + driveAddr + " does not have audio"); handle.writeLine("Disk in drive " + driveAddr + " does not have audio");
return Future.sync(false);
} }
drive.playAudio(); drive.playAudio();
@ -60,18 +56,15 @@ class Disk extends CLIApp {
var drive = Peripheral.instance.getDrive(driveAddr); var drive = Peripheral.instance.getDrive(driveAddr);
if (drive == null){ if (drive == null){
handle.writeLn("Drive not found: " + driveAddr); handle.writeLine("Drive not found: " + driveAddr);
return Future.sync(false);
} }
if (!drive.isDiskPresent()){ if (!drive.isDiskPresent()){
handle.writeLn("No disk in drive: " + driveAddr); handle.writeLine("No disk in drive: " + driveAddr);
return Future.sync(false);
} }
if (!drive.hasAudio()){ if (!drive.hasAudio()){
handle.writeLn("Disk in drive: " + driveAddr + " does not have audio"); handle.writeLine("Disk in drive: " + driveAddr + " does not have audio");
return Future.sync(false);
} }
drive.stopAudio(); drive.stopAudio();
@ -80,13 +73,11 @@ class Disk extends CLIApp {
var drive = Peripheral.instance.getDrive(driveAddr); var drive = Peripheral.instance.getDrive(driveAddr);
if (drive == null){ if (drive == null){
handle.writeLn("Drive not found: " + driveAddr); handle.writeLine("Drive not found: " + driveAddr);
return Future.sync(false);
} }
if (!drive.isDiskPresent()){ if (!drive.isDiskPresent()){
handle.writeLn("No disk in drive: " + driveAddr); handle.writeLine("No disk in drive: " + driveAddr);
return Future.sync(false);
} }
drive.ejectDisk(); drive.ejectDisk();
@ -95,43 +86,39 @@ class Disk extends CLIApp {
var label:String = handle.args[2]; var label:String = handle.args[2];
if (drive == null){ if (drive == null){
handle.writeLn("Drive not found: " + driveAddr); handle.writeLine("Drive not found: " + driveAddr);
return Future.sync(false);
} }
if (!drive.isDiskPresent()){ if (!drive.isDiskPresent()){
handle.writeLn("No disk in drive: " + driveAddr); handle.writeLine("No disk in drive: " + driveAddr);
return Future.sync(false);
} }
if (label == null || label == ""){ if (label == null || label == ""){
handle.writeLn(drive.getDiskLabel()); handle.writeLine(drive.getDiskLabel());
}else{ }else{
var err = drive.setDiskLabel(label); var err = drive.setDiskLabel(label);
if (err != null){ if (err != null){
handle.writeLn("Failed to set lable"); handle.writeLine("Failed to set lable");
return Future.sync(false);
} }
} }
case "help": case "help":
case null: case null:
printHelp(); printHelp();
default: default:
handle.writeLn("Unknown subcommand: " + subcommand); handle.writeLine("Unknown subcommand: " + subcommand);
printHelp(); printHelp();
return Future.sync(false);
} }
return Future.sync(true); return handle.close(true);
} }
private function printHelp() { private function printHelp() {
handle.writeLn("Usage: disk <subcommand> [args]"); handle.writeLine("Usage: disk <subcommand> [args]");
handle.writeLn("Subcommands:"); handle.writeLine("Subcommands:");
handle.writeLn(" ls"); handle.writeLine(" ls");
handle.writeLn(" play <drive>"); handle.writeLine(" play <drive>");
handle.writeLn(" stop <drive>"); handle.writeLine(" stop <drive>");
handle.writeLn(" eject <drive>"); handle.writeLine(" eject <drive>");
handle.writeLn(" label <drive> [label]"); handle.writeLine(" label <drive> [label]");
} }
} }

View File

@ -1,19 +1,19 @@
package bin; package bin;
import kernel.ps.ProcessHandle;
import kernel.ps.Process;
import kernel.gps.INS; import kernel.gps.INS;
import lib.Pos3; import lib.Pos3;
import lib.Vec.Vec3; import lib.Vec.Vec3;
import lib.cli.TermHandle;
import lib.cli.CLIApp;
using tink.CoreApi; using tink.CoreApi;
class GPS extends CLIApp { class GPS implements Process {
private var handle:TermHandle; private var handle:ProcessHandle;
public function new() {} public function new() {}
public function invoke(handle: TermHandle):Future<Bool> { public function run(handle: ProcessHandle):Void {
this.handle = handle; this.handle = handle;
var subcommand = handle.args[0]; var subcommand = handle.args[0];
@ -21,30 +21,37 @@ class GPS extends CLIApp {
switch (subcommand) { switch (subcommand) {
case "set": case "set":
return Future.sync(setManuelPos(subcommand_args)); handle.close(setManuelPos(subcommand_args));
case "status": case "status":
return Future.sync(getGPSStatus()); handle.close(getGPSStatus());
case "locate": case "locate":
kernel.gps.GPS.instance.locate(); kernel.gps.GPS.instance.locate().handle((pos)->{
return Future.sync(true); if (pos != null) {
case "ins": handle.writeLine('Position x:${pos.x} y:${pos.y} z:${pos.z}');
return INS.instance.align().isSuccess(); handle.close(true);
default: } else {
handle.writeLn("Unknown subcommand: " + subcommand); handle.writeLine("Position not available");
printHelp(); handle.close(false);
return Future.sync(false); }
});
case "ins":
INS.instance.align().handle(()->{
handle.writeLine("INS aligned");
handle.close(true);
});
default:
handle.writeLine("Unknown subcommand: " + subcommand);
printHelp();
handle.close(false);
} }
return Future.sync(true);
} }
private function printHelp(){ private function printHelp(){
handle.writeLn("GPS commands:"); handle.writeLine("GPS commands:");
handle.writeLn("set <x> <y> <z> - set manual position"); handle.writeLine("set <x> <y> <z> - set manual position");
handle.writeLn("status - get current position and accuracy"); handle.writeLine("status - get current position and accuracy");
handle.writeLn("locate - get current position"); handle.writeLine("locate - get current position");
handle.writeLn("ins - align INS"); handle.writeLine("ins - align INS");
} }
private function setManuelPos(args: Array<String>): Bool { private function setManuelPos(args: Array<String>): Bool {
@ -63,26 +70,26 @@ class GPS extends CLIApp {
var pos = kernel.gps.GPS.instance.getPosition(); var pos = kernel.gps.GPS.instance.getPosition();
if (pos != null) { if (pos != null) {
handle.writeLn('Position x:${pos.x} y:${pos.y} z:${pos.z}'); handle.writeLine('Position x:${pos.x} y:${pos.y} z:${pos.z}');
} else { } else {
handle.writeLn("Position not available"); handle.writeLine("Position not available");
return true; return true;
} }
var acc = kernel.gps.GPS.instance.getAccuracy(); var acc = kernel.gps.GPS.instance.getAccuracy();
if (acc == 1){ if (acc == 1){
handle.writeLn("Accuracy: Low"); handle.writeLine("Accuracy: Low");
} else if (acc == 2){ } else if (acc == 2){
handle.writeLn("Accuracy: Medium"); handle.writeLine("Accuracy: Medium");
} else if (acc == 3){ } else if (acc == 3){
handle.writeLn("Accuracy: High"); handle.writeLine("Accuracy: High");
} }
var ins = INS.instance.getHeading(); var ins = INS.instance.getHeading();
if (ins != null) { if (ins != null) {
handle.writeLn('INS heading: ${ins.x} y:${ins.y} z:${ins.z}'); handle.writeLine('INS heading: ${ins.x} y:${ins.y} z:${ins.z}');
} else { } else {
handle.writeLn("INS heading not available"); handle.writeLine("INS heading not available");
} }
return true; return true;

View File

@ -1,21 +1,16 @@
package bin; package bin;
import lib.cli.TermHandle; import kernel.ps.ProcessHandle;
import lib.cli.CLIApp; import kernel.ps.Process;
using tink.CoreApi; using tink.CoreApi;
class HelloWorld extends CLIApp { class HelloWorld implements Process {
public function new() {} public function new() {}
public function invoke(handle: TermHandle):Future<Bool> { public function run(handle:ProcessHandle) {
var world:String = "world"; handle.write("Hello World!");
if (handle.args.length > 0) { handle.close();
world = handle.args[0];
}
handle.write('Hello, $world!');
return Future.sync(true);
} }
} }

View File

@ -1,19 +1,19 @@
package bin; package bin;
import kernel.ps.ProcessHandle;
import kernel.ps.Process;
import kernel.peripherals.Peripherals.Peripheral; import kernel.peripherals.Peripherals.Peripheral;
import kernel.net.Routing; import kernel.net.Routing;
import haxe.ds.ReadOnlyArray; import haxe.ds.ReadOnlyArray;
import lib.cli.TermHandle;
import lib.cli.CLIApp;
using tink.CoreApi; using tink.CoreApi;
class Net extends CLIApp { class Net implements Process {
private var handle:TermHandle; private var handle:ProcessHandle;
public function new() {} public function new() {}
public function invoke(handle:TermHandle):Future<Bool> { public function run(handle:ProcessHandle):Void {
this.handle = handle; this.handle = handle;
var subcommand = handle.args[0]; var subcommand = handle.args[0];
@ -21,86 +21,82 @@ class Net extends CLIApp {
switch (subcommand) { switch (subcommand) {
case "route": case "route":
return Future.sync(route(subcommand_args)); route(subcommand_args);
return handle.close();
case "iface": case "iface":
return Future.sync(iface(subcommand_args)); iface(subcommand_args);
return handle.close();
case "help": case "help":
printHelp(); printHelp();
return Future.sync(true); return handle.close();
case "ping": case "ping":
return ping(subcommand_args); ping(subcommand_args);
// Closes itself
case "proto": case "proto":
return Future.sync(protos()); protos();
return handle.close();
default: default:
handle.writeLn("Unknown subcommand: " + subcommand); handle.write("Unknown subcommand: " + subcommand);
printHelp(); printHelp();
return Future.sync(false); return handle.close(false);
} }
} }
private function printHelp() { private function printHelp() {
handle.writeLn("net route"); handle.write("net route");
handle.writeLn("net iface"); handle.write("net iface");
handle.writeLn("net help"); handle.write("net help");
handle.writeLn("net proto"); handle.write("net proto");
} }
private function route(args:ReadOnlyArray<String>):Bool { private function route(args:ReadOnlyArray<String>):Void {
var routes = Routing.instance.getRouteTable(); var routes = Routing.instance.getRouteTable();
for(k => v in routes) { for(k => v in routes) {
handle.writeLn('${k} => ${v.interf.name()}(${v.cost})'); handle.write('${k} => ${v.interf.name()}(${v.cost})');
} }
return true;
} }
private function iface(args:ReadOnlyArray<String>):Bool { private function iface(args:ReadOnlyArray<String>):Bool {
var modems = Peripheral.instance.getModems(); var modems = Peripheral.instance.getModems();
for (modem in modems) { for (modem in modems) {
handle.writeLn(modem.name()); handle.write(modem.name());
} }
return true; return true;
} }
function ping(args:ReadOnlyArray<String>): Future<Bool> { function ping(args:ReadOnlyArray<String>): Void {
return new Future<Bool>(trigger -> {
if (args.length != 1) { if (args.length != 1) {
handle.writeLn("Usage: net ping id"); handle.write("Usage: net ping id");
trigger(false); return handle.close(false);
return null;
} }
var toID:Null<Int> = Std.parseInt(args[0]); var toID:Null<Int> = Std.parseInt(args[0]);
if (toID == null) { if (toID == null) {
handle.writeLn("Invalid ID"); handle.write("Invalid ID");
trigger(false); return handle.close(false);
return null;
} }
kernel.net.Net.instance.ping(toID).handle(result -> { kernel.net.Net.instance.ping(toID).handle(result -> {
switch (result){ switch (result){
case Success(_): case Success(_):
handle.writeLn("Ping succeeded"); handle.write("Ping succeeded");
trigger(true); return handle.close();
case Failure(failure): case Failure(failure):
handle.writeLn("Ping failed: " + failure); handle.write("Ping failed: " + failure);
trigger(false); return handle.close(false);
} }
}); });
});
} }
function protos():Bool { function protos():Void {
var protos = kernel.net.Net.instance.getActiveProtocols(); var protos = kernel.net.Net.instance.getActiveProtocols();
for (proto in protos) { for (proto in protos) {
handle.writeLn(proto); handle.write(proto);
} }
return true;
} }
} }

View File

@ -1,27 +1,27 @@
package bin; package bin;
import kernel.ps.ProcessHandle;
import kernel.ps.Process;
import kernel.peripherals.Peripherals.Peripheral; import kernel.peripherals.Peripherals.Peripheral;
import kernel.peripherals.Side; import kernel.peripherals.Side;
import lib.cli.TermHandle;
import lib.cli.CLIApp;
using tink.CoreApi; using tink.CoreApi;
class Redstone extends CLIApp { class Redstone implements Process {
public function new() {} public function new() {}
public function invoke(handle:TermHandle):Future<Bool> { public function run(handle: ProcessHandle):Void {
var subcommand = handle.args[0]; var subcommand = handle.args[0];
if (subcommand == null) { if (subcommand == null) {
handle.writeLn("Usage: redstone <on|off|get> <side>"); handle.write("Usage: redstone <on|off|get> <side>");
return Future.sync(false); return handle.close(false);
} }
var side:Null<Side> = handle.args[1]; var side:Null<Side> = handle.args[1];
if (side == null) { if (side == null) {
handle.writeLn("Invalid side"); handle.write("Invalid side");
return Future.sync(false); return handle.close(false);
} }
switch (subcommand) { switch (subcommand) {
@ -31,14 +31,14 @@ class Redstone extends CLIApp {
Peripheral.instance.getRedstone(side).setOutput(false); Peripheral.instance.getRedstone(side).setOutput(false);
case "get": case "get":
var value = Peripheral.instance.getRedstone(side).getAnalogInput(); var value = Peripheral.instance.getRedstone(side).getAnalogInput();
handle.writeLn("Analog input: " + value); handle.write("Analog input: " + value);
case "help": case "help":
handle.writeLn("Usage: redstone <on|off|get> <side>"); handle.write("Usage: redstone <on|off|get> <side>");
default: default:
handle.writeLn("Invalid subcommand"); handle.write("Invalid subcommand");
return Future.sync(false); return handle.close(false);
} }
return Future.sync(true); return handle.close();
} }
} }

View File

@ -1,8 +1,9 @@
package bin; package bin;
import kernel.ps.Process;
import kernel.ps.ProcessManager;
import kernel.ps.ProcessHandle;
import lib.ui.UIApp; import lib.ui.UIApp;
import lib.cli.TermHandle;
import lib.cli.CLIApp;
import lib.Color; import lib.Color;
import kernel.ui.WindowContext; import kernel.ui.WindowContext;
import kernel.ui.WindowManager; import kernel.ui.WindowManager;
@ -99,7 +100,17 @@ class Terminal extends UIApp {
var commandArgs:Array<String> = args.slice(1); var commandArgs:Array<String> = args.slice(1);
var hadInput = false; var hadInput = false;
var handle = new TermHandle(commandArgs, {
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) -> { onWrite: (s:String) -> {
if (!hadInput) { if (!hadInput) {
this.backlog.push(""); this.backlog.push("");
@ -108,30 +119,16 @@ class Terminal extends UIApp {
this.backlog[this.backlog.length - 1] += s; this.backlog[this.backlog.length - 1] += s;
this.redrawBacklog(); this.redrawBacklog();
}, },
onNewLine: () -> { onExit: (success:Bool) -> {
this.backlog.push("");
this.redrawBacklog();
}
});
var prog:CLIApp = getProgByName(commandName);
if (prog == null) {
this.backlog.push("Command not found: " + commandName);
this.redrawBacklog();
return;
}
this.context.setCursorBlink(false);
prog.invoke(handle).handle((exitCode) -> {
// Cleanup extra newline
if (this.backlog[this.backlog.length - 1] == "") { if (this.backlog[this.backlog.length - 1] == "") {
this.backlog.pop(); this.backlog.pop();
} }
this.redrawInput(); this.redrawInput();
}
}); });
this.context.setCursorBlink(false);
} }
private function parseArgs(command:String):Array<String> { private function parseArgs(command:String):Array<String> {
@ -144,7 +141,7 @@ class Terminal extends UIApp {
this.redrawBacklog(); this.redrawBacklog();
} }
private function getProgByName(name:String):CLIApp { private function getProgByName(name:String):Process {
switch (name) { switch (name) {
case "hello": case "hello":
return new HelloWorld(); return new HelloWorld();

View File

@ -1,7 +0,0 @@
package lib.cli;
using tink.CoreApi;
abstract class CLIApp {
public abstract function invoke(handle: TermHandle): Future<Bool>;
}

View File

@ -1,29 +0,0 @@
package lib.cli;
import haxe.ds.ReadOnlyArray;
typedef TermHandleEvents = {
onWrite: String->Void,
onNewLine: Void->Void,
}
class TermHandle {
public final args:ReadOnlyArray<String>;
private final events:TermHandleEvents;
@:allow(bin.Terminal)
private function new(args: Array<String>, events: TermHandleEvents) {
this.args = args;
this.events = events;
}
public function write(s:String) {
this.events.onWrite(s);
}
public function writeLn(s:String = "") {
if (s != "")
this.events.onWrite(s);
this.events.onNewLine();
}
}