BIG FORMATING COMMIT
This commit is contained in:
parent
088fce0aaa
commit
91972107eb
@ -7,4 +7,3 @@ class Startup {
|
||||
main.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,19 +8,19 @@ using Lambda;
|
||||
|
||||
class Disk extends CLIAppBase {
|
||||
public function new() {
|
||||
registerSyncSubcommand("ls", (args)->{
|
||||
registerSyncSubcommand("ls", (args) -> {
|
||||
Peripheral.getAllDrives().foreach(drive -> {
|
||||
var addr = drive.getAddr();
|
||||
var label = drive.getDiskLabel();
|
||||
var id = drive.getDiskID();
|
||||
|
||||
if (drive.isDiskPresent()){
|
||||
if (drive.hasAudio()){
|
||||
if (drive.isDiskPresent()) {
|
||||
if (drive.hasAudio()) {
|
||||
handle.writeLine('${addr} => ${label} [AUDIO]');
|
||||
}else{
|
||||
} else {
|
||||
handle.writeLine('${addr} => ${label} (${id})');
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
handle.writeLine('${addr} => [NO DISK]');
|
||||
}
|
||||
|
||||
@ -28,26 +28,26 @@ class Disk extends CLIAppBase {
|
||||
});
|
||||
});
|
||||
|
||||
registerSyncSubcommand("play", (args)->{
|
||||
if (args.length < 1){
|
||||
registerSyncSubcommand("play", (args) -> {
|
||||
if (args.length < 1) {
|
||||
handle.writeLine("Missing drive address");
|
||||
return false;
|
||||
}
|
||||
|
||||
return audioDiskPlayPause(args[0], true);
|
||||
},"<drive>");
|
||||
}, "<drive>");
|
||||
|
||||
registerSyncSubcommand("stop", (args) -> {
|
||||
if (args.length < 1){
|
||||
if (args.length < 1) {
|
||||
handle.writeLine("Missing drive address");
|
||||
return false;
|
||||
}
|
||||
|
||||
return audioDiskPlayPause(args[0], false);
|
||||
},"<drive>");
|
||||
}, "<drive>");
|
||||
|
||||
registerSyncSubcommand("eject", (args)->{
|
||||
if (args.length < 1){
|
||||
registerSyncSubcommand("eject", (args) -> {
|
||||
if (args.length < 1) {
|
||||
handle.writeLine("Missing drive address");
|
||||
return false;
|
||||
}
|
||||
@ -55,22 +55,22 @@ class Disk extends CLIAppBase {
|
||||
var driveAddr = args[0];
|
||||
var drive = Peripheral.getDrive(driveAddr);
|
||||
|
||||
if (drive == null){
|
||||
if (drive == null) {
|
||||
handle.writeLine("Drive not found: " + driveAddr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!drive.isDiskPresent()){
|
||||
if (!drive.isDiskPresent()) {
|
||||
handle.writeLine("No disk in drive: " + driveAddr);
|
||||
return false;
|
||||
}
|
||||
|
||||
drive.ejectDisk();
|
||||
return true;
|
||||
},"<drive>");
|
||||
}, "<drive>");
|
||||
|
||||
registerSyncSubcommand("lable",(args) -> {
|
||||
if (args.length < 1){
|
||||
registerSyncSubcommand("lable", (args) -> {
|
||||
if (args.length < 1) {
|
||||
handle.writeLine("Missing drive address");
|
||||
return false;
|
||||
}
|
||||
@ -79,49 +79,49 @@ class Disk extends CLIAppBase {
|
||||
var drive = Peripheral.getDrive(driveAddr);
|
||||
var label:String = args[1];
|
||||
|
||||
if (drive == null){
|
||||
if (drive == null) {
|
||||
handle.writeLine("Drive not found: " + driveAddr);
|
||||
}
|
||||
|
||||
if (!drive.isDiskPresent()){
|
||||
if (!drive.isDiskPresent()) {
|
||||
handle.writeLine("No disk in drive: " + driveAddr);
|
||||
}
|
||||
|
||||
if (label == null || label == ""){
|
||||
if (label == null || label == "") {
|
||||
handle.writeLine(drive.getDiskLabel());
|
||||
}else{
|
||||
var err = drive.setDiskLabel(label);
|
||||
if (err != null){
|
||||
} else {
|
||||
var err = drive.setDiskLabel(label);
|
||||
if (err != null) {
|
||||
handle.writeLine("Failed to set lable");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},"<drive> [label]");
|
||||
}, "<drive> [label]");
|
||||
}
|
||||
|
||||
private function audioDiskPlayPause(driveAddr: String, play: Bool): Bool {
|
||||
private function audioDiskPlayPause(driveAddr:String, play:Bool):Bool {
|
||||
var drive = Peripheral.getDrive(driveAddr);
|
||||
|
||||
if (drive == null){
|
||||
if (drive == null) {
|
||||
handle.writeLine("Drive not found: " + driveAddr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!drive.isDiskPresent()){
|
||||
if (!drive.isDiskPresent()) {
|
||||
handle.writeLine("No disk in drive: " + driveAddr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!drive.hasAudio()){
|
||||
if (!drive.hasAudio()) {
|
||||
handle.writeLine("Disk in drive: " + driveAddr + " does not have audio");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (play){
|
||||
if (play) {
|
||||
drive.playAudio();
|
||||
}else{
|
||||
} else {
|
||||
drive.stopAudio();
|
||||
}
|
||||
|
||||
|
@ -9,19 +9,19 @@ using tink.CoreApi;
|
||||
|
||||
class GPS extends CLIAppBase {
|
||||
public function new() {
|
||||
registerSyncSubcommand("set", (args)->{
|
||||
var x: Float = Std.parseFloat(args[0]);
|
||||
var y: Float = Std.parseFloat(args[1]);
|
||||
var z: Float = Std.parseFloat(args[2]);
|
||||
|
||||
var pos: Pos3 = new Vec3<Float>(x, y, z);
|
||||
|
||||
kernel.gps.GPS.setManualPosition(pos);
|
||||
|
||||
return true;
|
||||
},"<x> <y> <z>");
|
||||
registerSyncSubcommand("set", (args) -> {
|
||||
var x:Float = Std.parseFloat(args[0]);
|
||||
var y:Float = Std.parseFloat(args[1]);
|
||||
var z:Float = Std.parseFloat(args[2]);
|
||||
|
||||
registerSyncSubcommand("status",(args)->{
|
||||
var pos:Pos3 = new Vec3<Float>(x, y, z);
|
||||
|
||||
kernel.gps.GPS.setManualPosition(pos);
|
||||
|
||||
return true;
|
||||
}, "<x> <y> <z>");
|
||||
|
||||
registerSyncSubcommand("status", (args) -> {
|
||||
var pos = kernel.gps.GPS.getPosition();
|
||||
if (pos != null) {
|
||||
handle.writeLine('Position x:${pos.x} y:${pos.y} z:${pos.z}');
|
||||
@ -29,28 +29,28 @@ class GPS extends CLIAppBase {
|
||||
handle.writeLine("Position not available");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
var acc = kernel.gps.GPS.getAccuracy();
|
||||
if (acc == 1){
|
||||
if (acc == 1) {
|
||||
handle.writeLine("Accuracy: Low");
|
||||
} else if (acc == 2){
|
||||
} else if (acc == 2) {
|
||||
handle.writeLine("Accuracy: Medium");
|
||||
} else if (acc == 3){
|
||||
} else if (acc == 3) {
|
||||
handle.writeLine("Accuracy: High");
|
||||
}
|
||||
|
||||
|
||||
var ins = INS.getHeading();
|
||||
if (ins != null) {
|
||||
handle.writeLine('INS heading: ${ins.x} y:${ins.y} z:${ins.z}');
|
||||
} else {
|
||||
handle.writeLine("INS heading not available");
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
registerAsyncSubcommand("locate",(args)->{
|
||||
return kernel.gps.GPS.locate().map((pos)->{
|
||||
registerAsyncSubcommand("locate", (args) -> {
|
||||
return kernel.gps.GPS.locate().map((pos) -> {
|
||||
if (pos != null) {
|
||||
handle.writeLine('Position x:${pos.x} y:${pos.y} z:${pos.z}');
|
||||
} else {
|
||||
@ -60,8 +60,8 @@ class GPS extends CLIAppBase {
|
||||
});
|
||||
});
|
||||
|
||||
registerAsyncSubcommand("ins",(args)->{
|
||||
return INS.align().map((_)->{
|
||||
registerAsyncSubcommand("ins", (args) -> {
|
||||
return INS.align().map((_) -> {
|
||||
handle.writeLine("INS aligned");
|
||||
return true;
|
||||
});
|
||||
|
@ -7,7 +7,6 @@ import kernel.ps.Process;
|
||||
using tink.CoreApi;
|
||||
|
||||
class HelloWorld implements Process {
|
||||
|
||||
public function new() {}
|
||||
|
||||
public function run(handle:ProcessHandle) {
|
||||
@ -15,7 +14,7 @@ class HelloWorld implements Process {
|
||||
|
||||
var c = new HelloWorldServiceRPC(0);
|
||||
|
||||
c.getNumber().handle((res)->{
|
||||
c.getNumber().handle((res) -> {
|
||||
Log.debug("Got number: " + res);
|
||||
});
|
||||
|
||||
|
@ -8,18 +8,18 @@ using tink.CoreApi;
|
||||
|
||||
@:build(macros.rpc.RPC.buildRPC())
|
||||
class HelloWorldService implements Process {
|
||||
private var handle:ProcessHandle;
|
||||
private var handle:ProcessHandle;
|
||||
|
||||
public function new() {}
|
||||
public function new() {}
|
||||
|
||||
public function run(handle:ProcessHandle) {
|
||||
this.handle = handle;
|
||||
this.handle = handle;
|
||||
|
||||
RPC.generateRPCPackageHandle();
|
||||
}
|
||||
RPC.generateRPCPackageHandle();
|
||||
}
|
||||
|
||||
@rpc
|
||||
public function getNumber():Int{
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
@rpc
|
||||
public function getNumber():Int {
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ import kernel.ps.ProcessHandle;
|
||||
import kernel.ps.Process;
|
||||
|
||||
class ID implements Process {
|
||||
public function new() {}
|
||||
public function new() {}
|
||||
|
||||
public function run(handle:ProcessHandle) {
|
||||
handle.writeLine("ID: " + kernel.net.Net.networkID);
|
||||
handle.close();
|
||||
}
|
||||
handle.writeLine("ID: " + kernel.net.Net.networkID);
|
||||
handle.close();
|
||||
}
|
||||
}
|
||||
|
@ -4,64 +4,64 @@ import kernel.KernelSettings;
|
||||
import lib.CLIAppBase;
|
||||
|
||||
class KSettings extends CLIAppBase {
|
||||
public function new() {
|
||||
registerSyncSubcommand("get", (args)->{
|
||||
var key = args[0];
|
||||
public function new() {
|
||||
registerSyncSubcommand("get", (args) -> {
|
||||
var key = args[0];
|
||||
|
||||
if (key == null) {
|
||||
handle.writeLine("Key not specified");
|
||||
return false;
|
||||
}
|
||||
if (key == null) {
|
||||
handle.writeLine("Key not specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
var value = switch (key){
|
||||
case "hostname":
|
||||
KernelSettings.hostname;
|
||||
case "sitecontroller":
|
||||
Std.string(KernelSettings.siteController);
|
||||
default:
|
||||
null;
|
||||
}
|
||||
var value = switch (key) {
|
||||
case "hostname":
|
||||
KernelSettings.hostname;
|
||||
case "sitecontroller":
|
||||
Std.string(KernelSettings.siteController);
|
||||
default:
|
||||
null;
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
handle.writeLine("Key not found or not set");
|
||||
return false;
|
||||
}
|
||||
if (value == null) {
|
||||
handle.writeLine("Key not found or not set");
|
||||
return false;
|
||||
}
|
||||
|
||||
handle.writeLine(value);
|
||||
return true;
|
||||
}," <key>");
|
||||
handle.writeLine(value);
|
||||
return true;
|
||||
}, " <key>");
|
||||
|
||||
registerSyncSubcommand("set", (args)->{
|
||||
var key = args[0];
|
||||
registerSyncSubcommand("set", (args) -> {
|
||||
var key = args[0];
|
||||
|
||||
if (key == null) {
|
||||
handle.writeLine("Key not specified");
|
||||
return false;
|
||||
}
|
||||
if (key == null) {
|
||||
handle.writeLine("Key not specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
var value = args[1];
|
||||
var value = args[1];
|
||||
|
||||
if (value == null) {
|
||||
handle.writeLine("Value not specified");
|
||||
return false;
|
||||
}
|
||||
if (value == null) {
|
||||
handle.writeLine("Value not specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (key){
|
||||
case "hostname":
|
||||
KernelSettings.hostname = value;
|
||||
case "sitecontroller":
|
||||
KernelSettings.siteController = Std.parseInt(value);
|
||||
default:
|
||||
handle.writeLine("Key not found");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}," <key> <value>");
|
||||
switch (key) {
|
||||
case "hostname":
|
||||
KernelSettings.hostname = value;
|
||||
case "sitecontroller":
|
||||
KernelSettings.siteController = Std.parseInt(value);
|
||||
default:
|
||||
handle.writeLine("Key not found");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, " <key> <value>");
|
||||
|
||||
registerSyncSubcommand("list", (args)->{
|
||||
handle.writeLine("hostname");
|
||||
handle.writeLine("sitecontroller");
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
registerSyncSubcommand("list", (args) -> {
|
||||
handle.writeLine("hostname");
|
||||
handle.writeLine("sitecontroller");
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,12 @@ import lib.ui.UIApp;
|
||||
using tink.CoreApi;
|
||||
|
||||
class KernelLog implements Process {
|
||||
private var handle: ProcessHandle;
|
||||
private var ctx: WindowContext;
|
||||
private var handle:ProcessHandle;
|
||||
private var ctx:WindowContext;
|
||||
|
||||
public function new() {}
|
||||
|
||||
public function run(handle: ProcessHandle):Void {
|
||||
public function run(handle:ProcessHandle):Void {
|
||||
this.handle = handle;
|
||||
|
||||
var statelessCtx = handle.createStatelessWindowContext();
|
||||
@ -24,23 +24,23 @@ class KernelLog implements Process {
|
||||
|
||||
statelessCtx.setRenderFunc(this.render);
|
||||
|
||||
Log.onLog.handle(()->{
|
||||
Log.onLog.handle(() -> {
|
||||
statelessCtx.requestRender();
|
||||
});
|
||||
}
|
||||
|
||||
private function render() {
|
||||
ctx.clear();
|
||||
ctx.setCursorPos(0,0);
|
||||
ctx.setCursorPos(0, 0);
|
||||
|
||||
var lines = Log.getLines();
|
||||
var height = ctx.getSize().y;
|
||||
var start = MathI.max(lines.length - height,0);
|
||||
var start = MathI.max(lines.length - height, 0);
|
||||
|
||||
for (i in start...lines.length) {
|
||||
var line = lines[i];
|
||||
|
||||
switch (line.level){
|
||||
switch (line.level) {
|
||||
case Info:
|
||||
ctx.setTextColor(Color.White);
|
||||
ctx.write("[INFO] ");
|
||||
@ -59,7 +59,7 @@ class KernelLog implements Process {
|
||||
}
|
||||
|
||||
ctx.write(line.message);
|
||||
ctx.setCursorPos(0,ctx.getCursorPos().y + 1);
|
||||
ctx.setCursorPos(0, ctx.getCursorPos().y + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,17 @@ import kernel.ps.ProcessHandle;
|
||||
import kernel.ps.Process;
|
||||
|
||||
class LSPS implements Process {
|
||||
public function new() {}
|
||||
public function new() {}
|
||||
|
||||
public function run(handle:ProcessHandle) {
|
||||
var pids = ProcessManager.listProcesses();
|
||||
var pids = ProcessManager.listProcesses();
|
||||
|
||||
handle.writeLine('Count: ${pids.length}');
|
||||
handle.writeLine('Count: ${pids.length}');
|
||||
|
||||
for (pid in pids) {
|
||||
handle.writeLine('${pid}');
|
||||
}
|
||||
for (pid in pids) {
|
||||
handle.writeLine('${pid}');
|
||||
}
|
||||
|
||||
handle.close();
|
||||
}
|
||||
}
|
||||
handle.close();
|
||||
}
|
||||
}
|
||||
|
@ -8,17 +8,17 @@ using tink.CoreApi;
|
||||
|
||||
class Net extends CLIAppBase {
|
||||
public function new() {
|
||||
registerSyncSubcommand("route", (args)->{
|
||||
registerSyncSubcommand("route", (args) -> {
|
||||
var routes = Routing.getRouteTable();
|
||||
|
||||
for(k => v in routes) {
|
||||
for (k => v in routes) {
|
||||
handle.writeLine('${k} => ${v.interf.name()}(${v.cost})');
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
registerSyncSubcommand("iface", (args)->{
|
||||
registerSyncSubcommand("iface", (args) -> {
|
||||
var modems = Peripheral.getAllModems();
|
||||
|
||||
for (modem in modems) {
|
||||
@ -28,7 +28,7 @@ class Net extends CLIAppBase {
|
||||
return true;
|
||||
});
|
||||
|
||||
registerSyncSubcommand("proto",(args)->{
|
||||
registerSyncSubcommand("proto", (args) -> {
|
||||
var protos = kernel.net.Net.getActiveProtocols();
|
||||
|
||||
for (proto in protos) {
|
||||
@ -38,20 +38,20 @@ class Net extends CLIAppBase {
|
||||
return true;
|
||||
});
|
||||
|
||||
registerAsyncSubcommand("ping",(args)->{
|
||||
registerAsyncSubcommand("ping", (args) -> {
|
||||
if (args.length < 1) {
|
||||
return Future.sync(false);
|
||||
}
|
||||
|
||||
|
||||
var toID:Null<Int> = Std.parseInt(args[0]);
|
||||
|
||||
|
||||
if (toID == null) {
|
||||
handle.write("Invalid ID");
|
||||
return Future.sync(false);
|
||||
}
|
||||
|
||||
|
||||
return kernel.net.Net.ping(toID).map(result -> {
|
||||
switch (result){
|
||||
switch (result) {
|
||||
case Success(_):
|
||||
handle.write("Ping succeeded");
|
||||
case Failure(failure):
|
||||
@ -60,6 +60,6 @@ class Net extends CLIAppBase {
|
||||
|
||||
return true;
|
||||
});
|
||||
},"<id>");
|
||||
}, "<id>");
|
||||
}
|
||||
}
|
||||
|
@ -4,35 +4,36 @@ import kernel.peripherals.Peripherals.Peripheral;
|
||||
import lib.CLIAppBase;
|
||||
|
||||
class Perf extends CLIAppBase {
|
||||
public function new() {
|
||||
registerSyncSubcommand("inspect",(args)->{
|
||||
if (args.length < 1) return false;
|
||||
public function new() {
|
||||
registerSyncSubcommand("inspect", (args) -> {
|
||||
if (args.length < 1)
|
||||
return false;
|
||||
|
||||
var result = Peripheral.inspect(args[0]);
|
||||
var result = Peripheral.inspect(args[0]);
|
||||
|
||||
if (result == null){
|
||||
handle.writeLine("No peripheral found on side "+args[0]);
|
||||
return true;
|
||||
}
|
||||
if (result == null) {
|
||||
handle.writeLine("No peripheral found on side " + args[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
handle.writeLine("Types:");
|
||||
for (type in result.types){
|
||||
handle.writeLine(" "+type);
|
||||
}
|
||||
handle.writeLine("Types:");
|
||||
for (type in result.types) {
|
||||
handle.writeLine(" " + type);
|
||||
}
|
||||
|
||||
handle.writeLine("Methods:");
|
||||
for (method in result.methods){
|
||||
handle.writeLine(" "+method);
|
||||
}
|
||||
handle.writeLine("Methods:");
|
||||
for (method in result.methods) {
|
||||
handle.writeLine(" " + method);
|
||||
}
|
||||
|
||||
return true;
|
||||
},"<side>");
|
||||
return true;
|
||||
}, "<side>");
|
||||
|
||||
registerSyncSubcommand("list",(args)->{
|
||||
for (addr in Peripheral.getAllAddresses()){
|
||||
handle.writeLine('$addr => ${Peripheral.getTypes(addr).join(", ")}');
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
registerSyncSubcommand("list", (args) -> {
|
||||
for (addr in Peripheral.getAllAddresses()) {
|
||||
handle.writeLine('$addr => ${Peripheral.getTypes(addr).join(", ")}');
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -5,22 +5,22 @@ import kernel.peripherals.Peripherals.Peripheral;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
class Redstone extends CLIAppBase{
|
||||
class Redstone extends CLIAppBase {
|
||||
public function new() {
|
||||
registerSyncSubcommand("on", (args)-> {
|
||||
registerSyncSubcommand("on", (args) -> {
|
||||
Peripheral.getRedstone(args[0]).setOutput(true);
|
||||
return true;
|
||||
},"<side>");
|
||||
}, "<side>");
|
||||
|
||||
registerSyncSubcommand("off", (args)-> {
|
||||
registerSyncSubcommand("off", (args) -> {
|
||||
Peripheral.getRedstone(args[0]).setOutput(false);
|
||||
return true;
|
||||
},"<side>");
|
||||
}, "<side>");
|
||||
|
||||
registerSyncSubcommand("get", (args)-> {
|
||||
registerSyncSubcommand("get", (args) -> {
|
||||
var value = Peripheral.getRedstone(args[0]).getAnalogInput();
|
||||
handle.write("Analog input: " + value);
|
||||
return true;
|
||||
},"<side>");
|
||||
}, "<side>");
|
||||
}
|
||||
}
|
||||
|
@ -6,81 +6,80 @@ import lib.CLIAppBase;
|
||||
using tink.CoreApi;
|
||||
|
||||
class Service extends CLIAppBase {
|
||||
public function new() {
|
||||
registerSyncSubcommand("start", (args) ->{
|
||||
if (args.length < 1) {
|
||||
return false;
|
||||
}
|
||||
public function new() {
|
||||
registerSyncSubcommand("start", (args) -> {
|
||||
if (args.length < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var name = args[0];
|
||||
var name = args[0];
|
||||
|
||||
var result = ServiceManager.start(name);
|
||||
return handleResult(result);
|
||||
},"<name>");
|
||||
var result = ServiceManager.start(name);
|
||||
return handleResult(result);
|
||||
}, "<name>");
|
||||
|
||||
registerSyncSubcommand("stop", (args) ->{
|
||||
if (args.length < 1) {
|
||||
return false;
|
||||
}
|
||||
registerSyncSubcommand("stop", (args) -> {
|
||||
if (args.length < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var name = args[0];
|
||||
var name = args[0];
|
||||
|
||||
var result = ServiceManager.stop(name);
|
||||
return handleResult(result);
|
||||
},"<name>");
|
||||
var result = ServiceManager.stop(name);
|
||||
return handleResult(result);
|
||||
}, "<name>");
|
||||
|
||||
registerSyncSubcommand("register", (args) ->{
|
||||
if (args.length < 2) {
|
||||
return false;
|
||||
}
|
||||
registerSyncSubcommand("register", (args) -> {
|
||||
if (args.length < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var name = args[0];
|
||||
var binName = args[1];
|
||||
var rest = args.slice(2);
|
||||
var name = args[0];
|
||||
var binName = args[1];
|
||||
var rest = args.slice(2);
|
||||
|
||||
var result = ServiceManager.register(name, binName, rest);
|
||||
return handleResult(result);
|
||||
},"<name> <binary> [args...]");
|
||||
var result = ServiceManager.register(name, binName, rest);
|
||||
return handleResult(result);
|
||||
}, "<name> <binary> [args...]");
|
||||
|
||||
registerSyncSubcommand("unregister", (args) ->{
|
||||
if (args.length < 2) {
|
||||
return false;
|
||||
}
|
||||
registerSyncSubcommand("unregister", (args) -> {
|
||||
if (args.length < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var name = args[0];
|
||||
var name = args[0];
|
||||
|
||||
var result = ServiceManager.unregister(name);
|
||||
return handleResult(result);
|
||||
},"<name>");
|
||||
var result = ServiceManager.unregister(name);
|
||||
return handleResult(result);
|
||||
}, "<name>");
|
||||
|
||||
registerSyncSubcommand("list", (args) ->{
|
||||
|
||||
var list = ServiceManager.listRunning();
|
||||
|
||||
for (name in list) {
|
||||
this.handle.writeLine(name);
|
||||
}
|
||||
registerSyncSubcommand("list", (args) -> {
|
||||
var list = ServiceManager.listRunning();
|
||||
|
||||
return true;
|
||||
});
|
||||
for (name in list) {
|
||||
this.handle.writeLine(name);
|
||||
}
|
||||
|
||||
registerSyncSubcommand("enable", (args) ->{
|
||||
if (args.length < 1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
ServiceManager.enable(args[0]);
|
||||
return true;
|
||||
},"<name>");
|
||||
}
|
||||
registerSyncSubcommand("enable", (args) -> {
|
||||
if (args.length < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private function handleResult(res: Outcome<Noise,String>): Bool {
|
||||
switch (res) {
|
||||
case Success(_):
|
||||
return true;
|
||||
case Failure(e):
|
||||
this.handle.write(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
ServiceManager.enable(args[0]);
|
||||
return true;
|
||||
}, "<name>");
|
||||
}
|
||||
|
||||
private function handleResult(res:Outcome<Noise, String>):Bool {
|
||||
switch (res) {
|
||||
case Success(_):
|
||||
return true;
|
||||
case Failure(e):
|
||||
this.handle.write(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,18 +15,18 @@ class Terminal implements Process {
|
||||
private var handle:ProcessHandle;
|
||||
|
||||
private var ctx:WindowContext;
|
||||
private var requestRender: () -> Void;
|
||||
|
||||
private var requestRender:() -> Void;
|
||||
|
||||
private var input:String = "";
|
||||
private var backlog:Array<String> = [];
|
||||
private var history:Array<String> = [];
|
||||
private var historyIndex:Int = 0;
|
||||
|
||||
private var runningPID:PID = -1;
|
||||
private var runningPID:PID = -1;
|
||||
|
||||
public function new() {}
|
||||
|
||||
public function run(handle: ProcessHandle): Void {
|
||||
public function run(handle:ProcessHandle):Void {
|
||||
this.handle = handle;
|
||||
|
||||
var statelessContext = handle.createStatelessWindowContext();
|
||||
@ -38,7 +38,8 @@ class Terminal implements Process {
|
||||
|
||||
// Add input event handlers
|
||||
handle.addCallbackLink(this.ctx.onChar.handle(char -> {
|
||||
if (this.runningPID > 0) return;
|
||||
if (this.runningPID > 0)
|
||||
return;
|
||||
this.input += char;
|
||||
this.requestRender();
|
||||
}));
|
||||
@ -47,11 +48,13 @@ class Terminal implements Process {
|
||||
handle.addCallbackLink(this.ctx.onKey.handle(e -> {
|
||||
switch (e.keyCode) {
|
||||
case 259: // Backspace
|
||||
if (this.runningPID > 0) return;
|
||||
if (this.runningPID > 0)
|
||||
return;
|
||||
this.input = this.input.substr(0, this.input.length - 1);
|
||||
this.requestRender();
|
||||
case 257: // Enter
|
||||
if (this.runningPID > 0) return;
|
||||
if (this.runningPID > 0)
|
||||
return;
|
||||
this.backlog.push("> " + this.input);
|
||||
var command = this.input;
|
||||
this.input = "";
|
||||
@ -145,7 +148,7 @@ class Terminal implements Process {
|
||||
return;
|
||||
}
|
||||
|
||||
this.runningPID = ProcessManager.run(ps,{
|
||||
this.runningPID = ProcessManager.run(ps, {
|
||||
args: commandArgs,
|
||||
onWrite: (s:String) -> {
|
||||
if (s == "") {
|
||||
@ -159,7 +162,7 @@ class Terminal implements Process {
|
||||
}
|
||||
|
||||
for (line in s.split("\n")) {
|
||||
if (line == ""){
|
||||
if (line == "") {
|
||||
this.backlog.push("");
|
||||
} else {
|
||||
this.backlog[this.backlog.length - 1] += s;
|
||||
@ -170,7 +173,7 @@ class Terminal implements Process {
|
||||
this.backlog.shift();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.requestRender();
|
||||
},
|
||||
onExit: (success:Bool) -> {
|
||||
@ -205,7 +208,7 @@ class Terminal implements Process {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Type.createInstance(bin.c,[]);
|
||||
return Type.createInstance(bin.c, []);
|
||||
}
|
||||
|
||||
private function moveCursorToInput() {
|
||||
|
@ -6,32 +6,32 @@ using tink.CoreApi;
|
||||
|
||||
class Turtle extends CLIAppBase {
|
||||
public function new() {
|
||||
registerSyncSubcommand("forward", (args)->{
|
||||
registerSyncSubcommand("forward", (args) -> {
|
||||
return perform(kernel.turtle.Turtle.instance.forward());
|
||||
});
|
||||
|
||||
registerSyncSubcommand("back", (args)->{
|
||||
registerSyncSubcommand("back", (args) -> {
|
||||
return perform(kernel.turtle.Turtle.instance.back());
|
||||
});
|
||||
|
||||
registerSyncSubcommand("left", (args)->{
|
||||
registerSyncSubcommand("left", (args) -> {
|
||||
return perform(kernel.turtle.Turtle.instance.turnLeft());
|
||||
});
|
||||
|
||||
registerSyncSubcommand("right", (args)->{
|
||||
registerSyncSubcommand("right", (args) -> {
|
||||
return perform(kernel.turtle.Turtle.instance.turnRight());
|
||||
});
|
||||
|
||||
registerSyncSubcommand("up", (args)->{
|
||||
registerSyncSubcommand("up", (args) -> {
|
||||
return perform(kernel.turtle.Turtle.instance.up());
|
||||
});
|
||||
|
||||
registerSyncSubcommand("down", (args)->{
|
||||
registerSyncSubcommand("down", (args) -> {
|
||||
return perform(kernel.turtle.Turtle.instance.down());
|
||||
});
|
||||
}
|
||||
|
||||
private function perform(outcome: Outcome<Noise,String>): Bool {
|
||||
private function perform(outcome:Outcome<Noise, String>):Bool {
|
||||
switch outcome {
|
||||
case Success(_):
|
||||
return true;
|
||||
@ -40,5 +40,4 @@ class Turtle extends CLIAppBase {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,51 +8,51 @@ import lib.exporter.Import;
|
||||
import lib.CLIAppBase;
|
||||
|
||||
class Res extends CLIAppBase {
|
||||
public function new() {
|
||||
registerAsyncSubcommand("get", (args)->{
|
||||
var url = args[0];
|
||||
public function new() {
|
||||
registerAsyncSubcommand("get", (args) -> {
|
||||
var url = args[0];
|
||||
|
||||
return Import.get(url).map((res)->{
|
||||
switch (res){
|
||||
case Success(data):
|
||||
handle.writeLine(Std.string(data));
|
||||
case Failure(err):
|
||||
handle.writeLine("Error: ");
|
||||
handle.writeLine(Std.string(err));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},"<url>");
|
||||
return Import.get(url).map((res) -> {
|
||||
switch (res) {
|
||||
case Success(data):
|
||||
handle.writeLine(Std.string(data));
|
||||
case Failure(err):
|
||||
handle.writeLine("Error: ");
|
||||
handle.writeLine(Std.string(err));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}, "<url>");
|
||||
|
||||
registerAsyncSubcommand("register",(args)->{
|
||||
var srv: Null<ResManager> = ServiceManager.get("resmgr");
|
||||
registerAsyncSubcommand("register", (args) -> {
|
||||
var srv:Null<ResManager> = ServiceManager.get("resmgr");
|
||||
|
||||
var addr = args[0];
|
||||
var name = args[1];
|
||||
var addr = args[0];
|
||||
var name = args[1];
|
||||
|
||||
if (srv == null) {
|
||||
handle.writeLine("Error: resmgr not found");
|
||||
return false;
|
||||
}
|
||||
if (srv == null) {
|
||||
handle.writeLine("Error: resmgr not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
var perf: kernel.peripherals.Redstone = Peripheral.getRedstone(addr);
|
||||
var perf:kernel.peripherals.Redstone = Peripheral.getRedstone(addr);
|
||||
|
||||
if (perf == null) {
|
||||
handle.writeLine("Error: peripheral not found");
|
||||
return false;
|
||||
}
|
||||
if (perf == null) {
|
||||
handle.writeLine("Error: peripheral not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
return srv.register(name,new Export(perf)).map((res)->{
|
||||
switch (res){
|
||||
case Success(_):
|
||||
handle.writeLine("Success");
|
||||
return true;
|
||||
case Failure(err):
|
||||
handle.writeLine("Error: ");
|
||||
handle.writeLine(Std.string(err));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},"<addr> <name>");
|
||||
}
|
||||
}
|
||||
return srv.register(name, new Export(perf)).map((res) -> {
|
||||
switch (res) {
|
||||
case Success(_):
|
||||
handle.writeLine("Success");
|
||||
return true;
|
||||
case Failure(err):
|
||||
handle.writeLine("Error: ");
|
||||
handle.writeLine(Std.string(err));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}, "<addr> <name>");
|
||||
}
|
||||
}
|
||||
|
@ -14,78 +14,76 @@ import kernel.net.Package.GenericPackage;
|
||||
using tink.CoreApi;
|
||||
|
||||
class ResManager implements Process {
|
||||
private var handle:ProcessHandle;
|
||||
private var exports:Map<String,Export> = [];
|
||||
private var handle:ProcessHandle;
|
||||
private var exports:Map<String, Export> = [];
|
||||
|
||||
public function new() {}
|
||||
public function new() {}
|
||||
|
||||
public function run(handle:ProcessHandle) {
|
||||
this.handle = handle;
|
||||
Net.registerProto("res",handlePackage);
|
||||
load();
|
||||
}
|
||||
public function run(handle:ProcessHandle) {
|
||||
this.handle = handle;
|
||||
Net.registerProto("res", handlePackage);
|
||||
load();
|
||||
}
|
||||
|
||||
public function register(id: String, export: Export): Promise<Noise>{
|
||||
if (exports.exists(id)){
|
||||
return Promise.reject(new Error("Ressource already exists: " + id));
|
||||
}
|
||||
public function register(id:String, export:Export):Promise<Noise> {
|
||||
if (exports.exists(id)) {
|
||||
return Promise.reject(new Error("Ressource already exists: " + id));
|
||||
}
|
||||
|
||||
return registerName(id).next((success)->{
|
||||
exports.set(id,export);
|
||||
persist();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
return registerName(id).next((success) -> {
|
||||
exports.set(id, export);
|
||||
persist();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private function handlePackage(pack: GenericPackage){
|
||||
var requestPack: Package<Request> = cast pack;
|
||||
var id = requestPack.data.id;
|
||||
private function handlePackage(pack:GenericPackage) {
|
||||
var requestPack:Package<Request> = cast pack;
|
||||
var id = requestPack.data.id;
|
||||
|
||||
if (!exports.exists(id)){
|
||||
requestPack.respond(lib.exporter.Response.NotFound);
|
||||
return;
|
||||
}
|
||||
if (!exports.exists(id)) {
|
||||
requestPack.respond(lib.exporter.Response.NotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
var export = exports.get(id);
|
||||
var response = export.handleRequest(requestPack.data);
|
||||
var export = exports.get(id);
|
||||
var response = export.handleRequest(requestPack.data);
|
||||
|
||||
requestPack.respond(response);
|
||||
}
|
||||
requestPack.respond(response);
|
||||
}
|
||||
|
||||
private function registerName(id: String){
|
||||
return RessourceNames.register(id, Net.networkID);
|
||||
}
|
||||
private function registerName(id:String) {
|
||||
return RessourceNames.register(id, Net.networkID);
|
||||
}
|
||||
|
||||
private function persist(){
|
||||
var store = new KVStore("export");
|
||||
private function persist() {
|
||||
var store = new KVStore("export");
|
||||
|
||||
var saveExports: Array<{name: String, addr: String, type: String}> =
|
||||
[for (k => v in this.exports) {name: k, addr: v.getAddr(), type: v.getType()}];
|
||||
var saveExports:Array<{name:String, addr:String, type:String}> = [for (k => v in this.exports) {name: k, addr: v.getAddr(), type: v.getType()}];
|
||||
|
||||
store.set("exports",saveExports);
|
||||
store.set("exports", saveExports);
|
||||
|
||||
store.save();
|
||||
}
|
||||
store.save();
|
||||
}
|
||||
|
||||
private function load(){
|
||||
var store = new KVStore("export");
|
||||
private function load() {
|
||||
var store = new KVStore("export");
|
||||
|
||||
var savedExports: Array<{name: String, addr: String, type: String}> = store.get("exports",[]);
|
||||
var savedExports:Array<{name:String, addr:String, type:String}> = store.get("exports", []);
|
||||
|
||||
for (export in savedExports){
|
||||
var perph = Peripheral.getFromType(export.addr,export.type);
|
||||
for (export in savedExports) {
|
||||
var perph = Peripheral.getFromType(export.addr, export.type);
|
||||
|
||||
if (perph == null){
|
||||
handle.writeLine('Could not load export: ${export.name} on ${export.addr}');
|
||||
continue;
|
||||
}
|
||||
if (perph == null) {
|
||||
handle.writeLine('Could not load export: ${export.name} on ${export.addr}');
|
||||
continue;
|
||||
}
|
||||
|
||||
// I dont know if cast is the best way to do this
|
||||
// But since we know that this is a IExportable we can do this (I think)
|
||||
exports.set(export.name, new Export(cast perph));
|
||||
// I dont know if cast is the best way to do this
|
||||
// But since we know that this is a IExportable we can do this (I think)
|
||||
exports.set(export.name, new Export(cast perph));
|
||||
|
||||
handle.writeLine('Loaded export: ${export.name} on ${export.addr}');
|
||||
}
|
||||
|
||||
}
|
||||
handle.writeLine('Loaded export: ${export.name} on ${export.addr}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,46 +9,51 @@ import kernel.ps.ProcessHandle;
|
||||
import kernel.ps.Process;
|
||||
|
||||
class PFClient implements Process {
|
||||
private var handle:ProcessHandle;
|
||||
private var handle:ProcessHandle;
|
||||
|
||||
private var ctx: WindowContext;
|
||||
private var requestRender:Void -> Void;
|
||||
private var root:RootElement;
|
||||
private var ctx:WindowContext;
|
||||
private var requestRender:Void->Void;
|
||||
private var root:RootElement;
|
||||
|
||||
public function new() {}
|
||||
public function new() {}
|
||||
|
||||
public function run(handle:ProcessHandle) {
|
||||
this.handle = handle;
|
||||
this.handle = handle;
|
||||
|
||||
var stateless = handle.createStatelessWindowContext();
|
||||
this.ctx = stateless.ctx;
|
||||
this.requestRender = stateless.requestRender;
|
||||
var stateless = handle.createStatelessWindowContext();
|
||||
this.ctx = stateless.ctx;
|
||||
this.requestRender = stateless.requestRender;
|
||||
|
||||
stateless.setRenderFunc(this.render);
|
||||
stateless.setRenderFunc(this.render);
|
||||
|
||||
this.root = new RootElement();
|
||||
this.root.setTitle("Pathfinder");
|
||||
this.root = new RootElement();
|
||||
this.root.setTitle("Pathfinder");
|
||||
|
||||
this.ctx.delegateEvents(this.root);
|
||||
this.ctx.delegateEvents(this.root);
|
||||
|
||||
this.requestRender();
|
||||
}
|
||||
this.requestRender();
|
||||
}
|
||||
|
||||
private function render() {
|
||||
var acc = kernel.gps.GPS.getAccuracy();
|
||||
var pos: Pos3 = kernel.gps.GPS.getPosition() ?? {x: 0, y: 0, z: 0};
|
||||
private function render() {
|
||||
var acc = kernel.gps.GPS.getAccuracy();
|
||||
var pos:Pos3 = kernel.gps.GPS.getPosition() ?? {x: 0, y: 0, z: 0};
|
||||
|
||||
var childre: Array<UIElement> = [
|
||||
new TextElement('Acc: ${acc}'),
|
||||
new TextElement('Pos: X:${pos.x} Y:${pos.y} Z:${pos.z}'),
|
||||
new TextElement('UPDATE', { style: {bgColor: Gray}, uiEvents: {onClick: () -> {
|
||||
kernel.gps.GPS.locate().handle((pos) ->{
|
||||
this.requestRender();
|
||||
});
|
||||
}}}),
|
||||
];
|
||||
var childre:Array<UIElement> = [
|
||||
new TextElement('Acc: ${acc}'),
|
||||
new TextElement('Pos: X:${pos.x} Y:${pos.y} Z:${pos.z}'),
|
||||
new TextElement('UPDATE', {
|
||||
style: {bgColor: Gray},
|
||||
uiEvents: {
|
||||
onClick: () -> {
|
||||
kernel.gps.GPS.locate().handle((pos) -> {
|
||||
this.requestRender();
|
||||
});
|
||||
}
|
||||
}
|
||||
}),
|
||||
];
|
||||
|
||||
this.root.setChildren(childre);
|
||||
this.root.render(ctx.getSize()).renderToContext(ctx);
|
||||
}
|
||||
this.root.setChildren(childre);
|
||||
this.root.render(ctx.getSize()).renderToContext(ctx);
|
||||
}
|
||||
}
|
||||
|
@ -86,8 +86,8 @@ class SiteRessourceController implements Process {
|
||||
return ressources.get(name);
|
||||
}
|
||||
|
||||
private inline function list():Array<String> {
|
||||
return [ for (k in ressources.keys()) k];
|
||||
private inline function list():Array<String> {
|
||||
return [for (k in ressources.keys()) k];
|
||||
}
|
||||
|
||||
private function load() {
|
||||
|
@ -2,8 +2,8 @@ package kernel;
|
||||
|
||||
@:keep
|
||||
class DCEHack {
|
||||
// Dont actually call this
|
||||
public static function load():Array<kernel.ps.Process>{
|
||||
macros.DCEHack.dceGenerateCreate();
|
||||
}
|
||||
// Dont actually call this
|
||||
public static function load():Array<kernel.ps.Process> {
|
||||
macros.DCEHack.dceGenerateCreate();
|
||||
}
|
||||
}
|
||||
|
@ -3,22 +3,26 @@ package kernel;
|
||||
import cc.OS;
|
||||
|
||||
/**
|
||||
Make sure that a function is called at the end of the current event loop.
|
||||
Like setTimeout(func, 0) in JavaScript.
|
||||
Make sure that a function is called at the end of the current event loop.
|
||||
Like setTimeout(func, 0) in JavaScript.
|
||||
**/
|
||||
class EndOfLoop {
|
||||
private static var backlog:Array<Void -> Void> = [];
|
||||
private static var isQueued = false;
|
||||
private static var backlog:Array<Void->Void> = [];
|
||||
private static var isQueued = false;
|
||||
|
||||
public static function endOfLoop(func: Void -> Void) {
|
||||
backlog.push(func);
|
||||
if (!isQueued) { OS.queueEvent("endofloop", null); }
|
||||
}
|
||||
public static function endOfLoop(func:Void->Void) {
|
||||
backlog.push(func);
|
||||
if (!isQueued) {
|
||||
OS.queueEvent("endofloop", null);
|
||||
}
|
||||
}
|
||||
|
||||
@:allow(kernel.KernelEvents)
|
||||
private static function run() {
|
||||
for (func in backlog) { func(); }
|
||||
backlog = [];
|
||||
isQueued = false;
|
||||
}
|
||||
@:allow(kernel.KernelEvents)
|
||||
private static function run() {
|
||||
for (func in backlog) {
|
||||
func();
|
||||
}
|
||||
backlog = [];
|
||||
isQueued = false;
|
||||
}
|
||||
}
|
||||
|
@ -6,14 +6,14 @@ class Entrypoint {
|
||||
public static function main() {
|
||||
try {
|
||||
Init.initKernel();
|
||||
}catch(e){
|
||||
} catch (e) {
|
||||
Log.error('Error in init: ${e.toString()}');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Startup.main();
|
||||
}catch(e){
|
||||
} catch (e) {
|
||||
Log.error('Error in startup: ${e.toString()}');
|
||||
}
|
||||
}
|
||||
|
@ -14,11 +14,9 @@ import lib.Debug;
|
||||
import kernel.ui.WindowManager;
|
||||
import kernel.peripherals.Peripherals.Peripheral;
|
||||
import kernel.net.Net;
|
||||
|
||||
import kernel.DCEHack; // Important for DCE hack
|
||||
|
||||
class Init {
|
||||
|
||||
@:allow(kernel.KernelEvents)
|
||||
private static var mainEvent:MainEvent;
|
||||
|
||||
@ -30,7 +28,7 @@ class Init {
|
||||
WindowManager.init();
|
||||
MainTerm.instance = new MainTerm();
|
||||
|
||||
if (Turtle.isTurtle()){
|
||||
if (Turtle.isTurtle()) {
|
||||
Turtle.instance = new Turtle();
|
||||
}
|
||||
|
||||
@ -40,7 +38,7 @@ class Init {
|
||||
GPS.init();
|
||||
|
||||
// Register default terminate handler
|
||||
KernelEvents.onTerminate.handle(_->{
|
||||
KernelEvents.onTerminate.handle(_ -> {
|
||||
KernelEvents.shutdown();
|
||||
});
|
||||
|
||||
@ -50,7 +48,7 @@ class Init {
|
||||
FS.makeDir("/var/ns");
|
||||
}
|
||||
|
||||
Init.mainEvent = MainLoop.add(()->{
|
||||
Init.mainEvent = MainLoop.add(() -> {
|
||||
KernelEvents.startEventLoop();
|
||||
});
|
||||
|
||||
|
@ -19,6 +19,7 @@ class KernelEvents {
|
||||
Depends on: (Nothing)
|
||||
**/
|
||||
public static var onAlarm(default, null):Signal<Int>;
|
||||
|
||||
public static var onChar(default, null):Signal<String>;
|
||||
public static var onDisk(default, null):Signal<String>;
|
||||
public static var onDiskEject(default, null):Signal<String>;
|
||||
@ -93,10 +94,10 @@ class KernelEvents {
|
||||
private static final onWebsocketMessageTrigger:SignalTrigger<{url:String, message:String, isBinary:Bool}> = Signal.trigger();
|
||||
private static final onWebsocketSuccessTrigger:SignalTrigger<{url:String, handle:Any}> = Signal.trigger();
|
||||
|
||||
private static var stopLoop:Bool = false;
|
||||
private static var stopLoop:Bool = false;
|
||||
|
||||
@:allow(kernel.Init)
|
||||
private static function init() {
|
||||
private static function init() {
|
||||
onAlarm = onAlarmTrigger.asSignal();
|
||||
onChar = onCharTrigger.asSignal();
|
||||
onDisk = onDiskTrigger.asSignal();
|
||||
@ -133,21 +134,20 @@ class KernelEvents {
|
||||
Start pulling events. Blocking.
|
||||
**/
|
||||
@:allow(kernel.Init)
|
||||
private static function startEventLoop() {
|
||||
private static function startEventLoop() {
|
||||
while (!stopLoop) {
|
||||
var event:Table<Int, Dynamic> = pullEvents();
|
||||
|
||||
var eventName:String = event[1];
|
||||
try {
|
||||
fireSignal(eventName,event);
|
||||
}catch(e:Dynamic) {
|
||||
fireSignal(eventName, event);
|
||||
} catch (e:Dynamic) {
|
||||
Log.error('Error while handling event: $eventName: ${e}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function shutdown() {
|
||||
|
||||
// clearing screens
|
||||
for (screen in Peripheral.getAllScreens()) {
|
||||
screen.reset();
|
||||
@ -159,11 +159,11 @@ class KernelEvents {
|
||||
Init.mainEvent.stop();
|
||||
}
|
||||
|
||||
private static function pullEvents():Table<Int, Dynamic> {
|
||||
private static function pullEvents():Table<Int, Dynamic> {
|
||||
return cast TableTools.pack(Coroutine.yield(null));
|
||||
}
|
||||
|
||||
private static function fireSignal(eventName: String,event:Table<Int, Dynamic> ) {
|
||||
private static function fireSignal(eventName:String, event:Table<Int, Dynamic>) {
|
||||
switch eventName {
|
||||
case "alarm":
|
||||
onAlarmTrigger.trigger(event[2]);
|
||||
@ -252,36 +252,66 @@ class KernelEvents {
|
||||
}
|
||||
|
||||
@:allow(lib.Debug)
|
||||
private static function printListenerCount() {
|
||||
if (onAlarmTrigger.getLength() > 0) Log.debug("onAlarm: " + onAlarmTrigger.getLength());
|
||||
if (onCharTrigger.getLength() > 0) Log.debug("onChar: " + onCharTrigger.getLength());
|
||||
if (onDiskTrigger.getLength() > 0) Log.debug("onDisk: " + onDiskTrigger.getLength());
|
||||
if (onDiskEjectTrigger.getLength() > 0) Log.debug("onDiskEject: " + onDiskEjectTrigger.getLength());
|
||||
if (onHttpCheckTrigger.getLength() > 0) Log.debug("onHttpCheck: " + onHttpCheckTrigger.getLength());
|
||||
if (onHttpFailureTrigger.getLength() > 0) Log.debug("onHttpFailure: " + onHttpFailureTrigger.getLength());
|
||||
if (onHttpSuccessTrigger.getLength() > 0) Log.debug("onHttpSuccess: " + onHttpSuccessTrigger.getLength());
|
||||
if (onKeyTrigger.getLength() > 0) Log.debug("onKey: " + onKeyTrigger.getLength());
|
||||
if (onKeyUpTrigger.getLength() > 0) Log.debug("onKeyUp: " + onKeyUpTrigger.getLength());
|
||||
if (onModemMessageTrigger.getLength() > 0) Log.debug("onModemMessage: " + onModemMessageTrigger.getLength());
|
||||
if (onMonitorResizeTrigger.getLength() > 0) Log.debug("onMonitorResize: " + onMonitorResizeTrigger.getLength());
|
||||
if (onMonitorTouchTrigger.getLength() > 0) Log.debug("onMonitorTouch: " + onMonitorTouchTrigger.getLength());
|
||||
if (onMouseClickTrigger.getLength() > 0) Log.debug("onMouseClick: " + onMouseClickTrigger.getLength());
|
||||
if (onMouseDragTrigger.getLength() > 0) Log.debug("onMouseDrag: " + onMouseDragTrigger.getLength());
|
||||
if (onMouseScrollTrigger.getLength() > 0) Log.debug("onMouseScroll: " + onMouseScrollTrigger.getLength());
|
||||
if (onMouseUpTrigger.getLength() > 0) Log.debug("onMouseUp: " + onMouseUpTrigger.getLength());
|
||||
if (onPasteTrigger.getLength() > 0) Log.debug("onPaste: " + onPasteTrigger.getLength());
|
||||
if (onPeripheralTrigger.getLength() > 0) Log.debug("onPeripheral: " + onPeripheralTrigger.getLength());
|
||||
if (onPeripheralDetachTrigger.getLength() > 0) Log.debug("onPeripheralDetach: " + onPeripheralDetachTrigger.getLength());
|
||||
if (onRedstoneTrigger.getLength() > 0) Log.debug("onRedstone: " + onRedstoneTrigger.getLength());
|
||||
if (onSpeakerAudioEmptyTrigger.getLength() > 0) Log.debug("onSpeakerAudioEmpty: " + onSpeakerAudioEmptyTrigger.getLength());
|
||||
if (onTaskCompleteTrigger.getLength() > 0) Log.debug("onTaskComplete: " + onTaskCompleteTrigger.getLength());
|
||||
if (onTermResizeTrigger.getLength() > 0) Log.debug("onTermResize: " + onTermResizeTrigger.getLength());
|
||||
if (onTerminateTrigger.getLength() > 0) Log.debug("onTerminate: " + onTerminateTrigger.getLength());
|
||||
if (onTimerTrigger.getLength() > 0) Log.debug("onTimer: " + onTimerTrigger.getLength());
|
||||
if (onTurtleInventoryTrigger.getLength() > 0) Log.debug("onTurtleInventory: " + onTurtleInventoryTrigger.getLength());
|
||||
if (onWebsocketCloseTrigger.getLength() > 0) Log.debug("onWebsocketClose: " + onWebsocketCloseTrigger.getLength());
|
||||
if (onWebsocketFailureTrigger.getLength() > 0) Log.debug("onWebsocketFailure: " + onWebsocketFailureTrigger.getLength());
|
||||
if (onWebsocketMessageTrigger.getLength() > 0) Log.debug("onWebsocketMessage: " + onWebsocketMessageTrigger.getLength());
|
||||
if (onWebsocketSuccessTrigger.getLength() > 0) Log.debug("onWebsocketSuccess: " + onWebsocketSuccessTrigger.getLength());
|
||||
private static function printListenerCount() {
|
||||
if (onAlarmTrigger.getLength() > 0)
|
||||
Log.debug("onAlarm: " + onAlarmTrigger.getLength());
|
||||
if (onCharTrigger.getLength() > 0)
|
||||
Log.debug("onChar: " + onCharTrigger.getLength());
|
||||
if (onDiskTrigger.getLength() > 0)
|
||||
Log.debug("onDisk: " + onDiskTrigger.getLength());
|
||||
if (onDiskEjectTrigger.getLength() > 0)
|
||||
Log.debug("onDiskEject: " + onDiskEjectTrigger.getLength());
|
||||
if (onHttpCheckTrigger.getLength() > 0)
|
||||
Log.debug("onHttpCheck: " + onHttpCheckTrigger.getLength());
|
||||
if (onHttpFailureTrigger.getLength() > 0)
|
||||
Log.debug("onHttpFailure: " + onHttpFailureTrigger.getLength());
|
||||
if (onHttpSuccessTrigger.getLength() > 0)
|
||||
Log.debug("onHttpSuccess: " + onHttpSuccessTrigger.getLength());
|
||||
if (onKeyTrigger.getLength() > 0)
|
||||
Log.debug("onKey: " + onKeyTrigger.getLength());
|
||||
if (onKeyUpTrigger.getLength() > 0)
|
||||
Log.debug("onKeyUp: " + onKeyUpTrigger.getLength());
|
||||
if (onModemMessageTrigger.getLength() > 0)
|
||||
Log.debug("onModemMessage: " + onModemMessageTrigger.getLength());
|
||||
if (onMonitorResizeTrigger.getLength() > 0)
|
||||
Log.debug("onMonitorResize: " + onMonitorResizeTrigger.getLength());
|
||||
if (onMonitorTouchTrigger.getLength() > 0)
|
||||
Log.debug("onMonitorTouch: " + onMonitorTouchTrigger.getLength());
|
||||
if (onMouseClickTrigger.getLength() > 0)
|
||||
Log.debug("onMouseClick: " + onMouseClickTrigger.getLength());
|
||||
if (onMouseDragTrigger.getLength() > 0)
|
||||
Log.debug("onMouseDrag: " + onMouseDragTrigger.getLength());
|
||||
if (onMouseScrollTrigger.getLength() > 0)
|
||||
Log.debug("onMouseScroll: " + onMouseScrollTrigger.getLength());
|
||||
if (onMouseUpTrigger.getLength() > 0)
|
||||
Log.debug("onMouseUp: " + onMouseUpTrigger.getLength());
|
||||
if (onPasteTrigger.getLength() > 0)
|
||||
Log.debug("onPaste: " + onPasteTrigger.getLength());
|
||||
if (onPeripheralTrigger.getLength() > 0)
|
||||
Log.debug("onPeripheral: " + onPeripheralTrigger.getLength());
|
||||
if (onPeripheralDetachTrigger.getLength() > 0)
|
||||
Log.debug("onPeripheralDetach: " + onPeripheralDetachTrigger.getLength());
|
||||
if (onRedstoneTrigger.getLength() > 0)
|
||||
Log.debug("onRedstone: " + onRedstoneTrigger.getLength());
|
||||
if (onSpeakerAudioEmptyTrigger.getLength() > 0)
|
||||
Log.debug("onSpeakerAudioEmpty: " + onSpeakerAudioEmptyTrigger.getLength());
|
||||
if (onTaskCompleteTrigger.getLength() > 0)
|
||||
Log.debug("onTaskComplete: " + onTaskCompleteTrigger.getLength());
|
||||
if (onTermResizeTrigger.getLength() > 0)
|
||||
Log.debug("onTermResize: " + onTermResizeTrigger.getLength());
|
||||
if (onTerminateTrigger.getLength() > 0)
|
||||
Log.debug("onTerminate: " + onTerminateTrigger.getLength());
|
||||
if (onTimerTrigger.getLength() > 0)
|
||||
Log.debug("onTimer: " + onTimerTrigger.getLength());
|
||||
if (onTurtleInventoryTrigger.getLength() > 0)
|
||||
Log.debug("onTurtleInventory: " + onTurtleInventoryTrigger.getLength());
|
||||
if (onWebsocketCloseTrigger.getLength() > 0)
|
||||
Log.debug("onWebsocketClose: " + onWebsocketCloseTrigger.getLength());
|
||||
if (onWebsocketFailureTrigger.getLength() > 0)
|
||||
Log.debug("onWebsocketFailure: " + onWebsocketFailureTrigger.getLength());
|
||||
if (onWebsocketMessageTrigger.getLength() > 0)
|
||||
Log.debug("onWebsocketMessage: " + onWebsocketMessageTrigger.getLength());
|
||||
if (onWebsocketSuccessTrigger.getLength() > 0)
|
||||
Log.debug("onWebsocketSuccess: " + onWebsocketSuccessTrigger.getLength());
|
||||
}
|
||||
}
|
||||
|
@ -6,51 +6,53 @@ import lib.KVStore;
|
||||
import cc.Settings;
|
||||
|
||||
class KernelSettings {
|
||||
private static inline function setAllowStartup(value: Bool) {
|
||||
Settings.set("shell.allow_startup", value);
|
||||
}
|
||||
private static inline function setAllowStartup(value:Bool) {
|
||||
Settings.set("shell.allow_startup", value);
|
||||
}
|
||||
|
||||
private static inline function setAllowStartupFromFloppy(value: Bool) {
|
||||
Settings.set("shell.allow_disk_startup", value);
|
||||
}
|
||||
private static inline function setAllowStartupFromFloppy(value:Bool) {
|
||||
Settings.set("shell.allow_disk_startup", value);
|
||||
}
|
||||
|
||||
private static function set(name: String, value: Dynamic) {
|
||||
var kvstore = new KVStore("kernel");
|
||||
kvstore.set(name, value);
|
||||
kvstore.save();
|
||||
}
|
||||
private static function set(name:String, value:Dynamic) {
|
||||
var kvstore = new KVStore("kernel");
|
||||
kvstore.set(name, value);
|
||||
kvstore.save();
|
||||
}
|
||||
|
||||
private static function get(name: String): Null<Dynamic> {
|
||||
var kvstore = new KVStore("kernel");
|
||||
return kvstore.get(name);
|
||||
}
|
||||
private static function get(name:String):Null<Dynamic> {
|
||||
var kvstore = new KVStore("kernel");
|
||||
return kvstore.get(name);
|
||||
}
|
||||
|
||||
public static var hostname(get,set): String;
|
||||
private static var _hostname:String = get("hostname");
|
||||
private static inline function get_hostname():String {
|
||||
public static var hostname(get, set):String;
|
||||
private static var _hostname:String = get("hostname");
|
||||
|
||||
private static inline function get_hostname():String {
|
||||
return _hostname;
|
||||
}
|
||||
|
||||
private static inline function set_hostname(value:String):String {
|
||||
OS.setComputerLabel(value);
|
||||
set("hostname", value);
|
||||
_hostname = value;
|
||||
return value;
|
||||
private static inline function set_hostname(value:String):String {
|
||||
OS.setComputerLabel(value);
|
||||
set("hostname", value);
|
||||
_hostname = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static var siteController(get,set): NetworkID;
|
||||
private static var _siteController:NetworkID = get("siteController");
|
||||
public static var siteController(get, set):NetworkID;
|
||||
private static var _siteController:NetworkID = get("siteController");
|
||||
|
||||
private static function get_siteController():NetworkID {
|
||||
return _siteController;
|
||||
}
|
||||
|
||||
private static function set_siteController(value:NetworkID):NetworkID {
|
||||
if (value == null) {
|
||||
return get_siteController();
|
||||
}
|
||||
if (value == null) {
|
||||
return get_siteController();
|
||||
}
|
||||
|
||||
set("siteController", value);
|
||||
_siteController = value;
|
||||
return value;
|
||||
set("siteController", value);
|
||||
_siteController = value;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
@ -100,6 +100,6 @@ class MainTerm implements TermWriteable {
|
||||
this.setBackgroundColor(Black);
|
||||
this.setTextColor(White);
|
||||
this.clear();
|
||||
this.setCursorPos(0,0);
|
||||
this.setCursorPos(0, 0);
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ package kernel.binstore;
|
||||
import kernel.ps.Process;
|
||||
|
||||
/**
|
||||
Represents a callable program.
|
||||
Represents a callable program.
|
||||
**/
|
||||
typedef Bin = {
|
||||
c: Class<Process>,
|
||||
name: String,
|
||||
aliases: Array<String>,
|
||||
c:Class<Process>,
|
||||
name:String,
|
||||
aliases:Array<String>,
|
||||
}
|
||||
|
@ -22,53 +22,53 @@ import bin.Disk;
|
||||
import haxe.ds.ReadOnlyArray;
|
||||
|
||||
class BinStore {
|
||||
private static final store:ReadOnlyArray<Bin> = [
|
||||
{c: Disk, name: "Disk", aliases: ["disk"]},
|
||||
{c: GPS, name: "GPS", aliases: ["gps"]},
|
||||
{c: HelloWorld, name: "HelloWorld", aliases: ["hello"]},
|
||||
{c: KernelLog, name: "KernelLog", aliases: ["log"]},
|
||||
{c: Net, name: "Net", aliases: ["net"]},
|
||||
{c: Redstone, name: "Redstone", aliases: ["redstone","rs"]},
|
||||
{c: Terminal, name: "Terminal", aliases: ["terminal","term"]},
|
||||
{c: Turtle, name: "Turtle", aliases: ["turtle"]},
|
||||
{c: LSPS, name: "PM", aliases: ["lsps"]},
|
||||
{c: Service, name: "Service", aliases: ["service","srv"]},
|
||||
{c: HelloWorldService, name: "HelloWorldService", aliases: ["hello-service"] },
|
||||
{c: SiteRessourceController, name: "SiteRessourceController", aliases: ["srsc"]},
|
||||
{c: CLI, name: "SRSC CLI", aliases: ["srsc-cli"]},
|
||||
{c: Perf, name: "Perf", aliases: ["perf"]},
|
||||
{c: KSettings, name: "KSettings", aliases: ["ksettings","ks"]},
|
||||
{c: ResManager, name: "ResManager", aliases: ["resmanager","resmgr"]},
|
||||
{c: Res, name: "Res", aliases: ["res"]},
|
||||
{c: ID , name: "ID", aliases: ["id"]},
|
||||
{c: PFClient, name: "PFClient", aliases: ["pfclient"]}
|
||||
];
|
||||
private static final store:ReadOnlyArray<Bin> = [
|
||||
{c: Disk, name: "Disk", aliases: ["disk"]},
|
||||
{c: GPS, name: "GPS", aliases: ["gps"]},
|
||||
{c: HelloWorld, name: "HelloWorld", aliases: ["hello"]},
|
||||
{c: KernelLog, name: "KernelLog", aliases: ["log"]},
|
||||
{c: Net, name: "Net", aliases: ["net"]},
|
||||
{c: Redstone, name: "Redstone", aliases: ["redstone", "rs"]},
|
||||
{c: Terminal, name: "Terminal", aliases: ["terminal", "term"]},
|
||||
{c: Turtle, name: "Turtle", aliases: ["turtle"]},
|
||||
{c: LSPS, name: "PM", aliases: ["lsps"]},
|
||||
{c: Service, name: "Service", aliases: ["service", "srv"]},
|
||||
{c: HelloWorldService, name: "HelloWorldService", aliases: ["hello-service"]},
|
||||
{c: SiteRessourceController, name: "SiteRessourceController", aliases: ["srsc"]},
|
||||
{c: CLI, name: "SRSC CLI", aliases: ["srsc-cli"]},
|
||||
{c: Perf, name: "Perf", aliases: ["perf"]},
|
||||
{c: KSettings, name: "KSettings", aliases: ["ksettings", "ks"]},
|
||||
{c: ResManager, name: "ResManager", aliases: ["resmanager", "resmgr"]},
|
||||
{c: Res, name: "Res", aliases: ["res"]},
|
||||
{c: ID, name: "ID", aliases: ["id"]},
|
||||
{c: PFClient, name: "PFClient", aliases: ["pfclient"]}
|
||||
];
|
||||
|
||||
public static function getBinByName(name:String):Null<Bin> {
|
||||
for (bin in store) {
|
||||
if (bin.name == name) {
|
||||
return bin;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static function getBinByName(name:String):Null<Bin> {
|
||||
for (bin in store) {
|
||||
if (bin.name == name) {
|
||||
return bin;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getBinByAlias(alias:String):Null<Bin> {
|
||||
for (bin in store) {
|
||||
for (a in bin.aliases) {
|
||||
if (a == alias) {
|
||||
return bin;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static function getBinByAlias(alias:String):Null<Bin> {
|
||||
for (bin in store) {
|
||||
for (a in bin.aliases) {
|
||||
if (a == alias) {
|
||||
return bin;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getNameByAlias(alias: String): String {
|
||||
var bin = getBinByAlias(alias);
|
||||
if (bin == null) {
|
||||
return null;
|
||||
}
|
||||
return bin.name;
|
||||
}
|
||||
public static function getNameByAlias(alias:String):String {
|
||||
var bin = getBinByAlias(alias);
|
||||
if (bin == null) {
|
||||
return null;
|
||||
}
|
||||
return bin.name;
|
||||
}
|
||||
}
|
||||
|
@ -13,79 +13,79 @@ using lua.Table;
|
||||
Wrapper to interact with the filesystem.
|
||||
**/
|
||||
class FS {
|
||||
public static inline function list(path: String):ReadOnlyArray<String> {
|
||||
public static inline function list(path:String):ReadOnlyArray<String> {
|
||||
return FileSystem.list(path).toArray();
|
||||
}
|
||||
|
||||
public static inline function combine(base: String, part: String): String {
|
||||
return FileSystem.combine(base,part);
|
||||
public static inline function combine(base:String, part:String):String {
|
||||
return FileSystem.combine(base, part);
|
||||
}
|
||||
|
||||
public static inline function getName(path: String): String {
|
||||
public static inline function getName(path:String):String {
|
||||
return FileSystem.getName(path);
|
||||
}
|
||||
|
||||
public static inline function getDir(path: String): String {
|
||||
public static inline function getDir(path:String):String {
|
||||
return FileSystem.getDir(path);
|
||||
}
|
||||
|
||||
public static inline function getSize(path: String):Int {
|
||||
public static inline function getSize(path:String):Int {
|
||||
return FileSystem.getSize(path);
|
||||
}
|
||||
|
||||
public static inline function exists(path: String):Bool {
|
||||
public static inline function exists(path:String):Bool {
|
||||
return FileSystem.exists(path);
|
||||
}
|
||||
|
||||
public static inline function isDir(path: String): Bool {
|
||||
public static inline function isDir(path:String):Bool {
|
||||
return FileSystem.isDir(path);
|
||||
}
|
||||
|
||||
public static inline function isReadOnly(path: String):Bool {
|
||||
public static inline function isReadOnly(path:String):Bool {
|
||||
return FileSystem.isReadOnly(path);
|
||||
}
|
||||
|
||||
public static inline function makeDir(path: String):Void {
|
||||
public static inline function makeDir(path:String):Void {
|
||||
FileSystem.makeDir(path);
|
||||
}
|
||||
|
||||
public static inline function move(src:String,dest:String):Void {
|
||||
FileSystem.move(src,dest);
|
||||
public static inline function move(src:String, dest:String):Void {
|
||||
FileSystem.move(src, dest);
|
||||
}
|
||||
|
||||
public static inline function copy(src:String,dest:String):Void {
|
||||
FileSystem.copy(src,dest);
|
||||
public static inline function copy(src:String, dest:String):Void {
|
||||
FileSystem.copy(src, dest);
|
||||
}
|
||||
|
||||
public static inline function delete(path: String):Void {
|
||||
public static inline function delete(path:String):Void {
|
||||
FileSystem.delete(path);
|
||||
}
|
||||
|
||||
public static inline function openRead(path:String): ReadHandle{
|
||||
return FileSystem.open(path,Read);
|
||||
public static inline function openRead(path:String):ReadHandle {
|
||||
return FileSystem.open(path, Read);
|
||||
}
|
||||
|
||||
public static inline function openWrite(path: String): WriteHandle {
|
||||
return FileSystem.open(path,Write);
|
||||
public static inline function openWrite(path:String):WriteHandle {
|
||||
return FileSystem.open(path, Write);
|
||||
}
|
||||
|
||||
public static inline function openAppend(path: String): WriteHandle {
|
||||
return FileSystem.open(path,Append);
|
||||
public static inline function openAppend(path:String):WriteHandle {
|
||||
return FileSystem.open(path, Append);
|
||||
}
|
||||
|
||||
public static inline function openReadBinary(path:String): ReadBinaryHandle {
|
||||
return FileSystem.open(path,BinaryRead);
|
||||
public static inline function openReadBinary(path:String):ReadBinaryHandle {
|
||||
return FileSystem.open(path, BinaryRead);
|
||||
}
|
||||
|
||||
public static inline function openWriteBinary(path: String): WriteBinaryHandle {
|
||||
return FileSystem.open(path,BinaryWrite);
|
||||
public static inline function openWriteBinary(path:String):WriteBinaryHandle {
|
||||
return FileSystem.open(path, BinaryWrite);
|
||||
}
|
||||
|
||||
public static inline function openAppendBinary(path: String): WriteBinaryHandle {
|
||||
return FileSystem.open(path,BinaryAppend);
|
||||
public static inline function openAppendBinary(path:String):WriteBinaryHandle {
|
||||
return FileSystem.open(path, BinaryAppend);
|
||||
}
|
||||
|
||||
public static inline function find(pattern: String):ReadOnlyArray<String> {
|
||||
public static inline function find(pattern:String):ReadOnlyArray<String> {
|
||||
return FileSystem.find(pattern).toArray();
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ class FS {
|
||||
return FileSystem.getCapacity(path);
|
||||
}
|
||||
|
||||
public static inline function attributes(path: String):FileAttributes {
|
||||
public static inline function attributes(path:String):FileAttributes {
|
||||
return FileSystem.attributes(path);
|
||||
}
|
||||
}
|
||||
|
@ -5,107 +5,103 @@ import cc.FileSystem.FileHandle;
|
||||
using tink.CoreApi;
|
||||
|
||||
abstract ReadHandle(FileHandle) from FileHandle {
|
||||
|
||||
public inline function new(handle:FileHandle) {
|
||||
this = handle;
|
||||
}
|
||||
|
||||
public inline function readLine(?withTrailing:Bool = false):Null<String>{
|
||||
public inline function readLine(?withTrailing:Bool = false):Null<String> {
|
||||
return this.readLine(withTrailing);
|
||||
}
|
||||
|
||||
public inline function readAll():Null<String>{
|
||||
public inline function readAll():Null<String> {
|
||||
return this.readAll();
|
||||
}
|
||||
|
||||
public inline function read(?count:Int = 1):Null<String>{
|
||||
public inline function read(?count:Int = 1):Null<String> {
|
||||
return this.read(count);
|
||||
}
|
||||
|
||||
public inline function close():Void{
|
||||
public inline function close():Void {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
abstract WriteHandle(FileHandle) from FileHandle {
|
||||
|
||||
public inline function new(handle:FileHandle) {
|
||||
this = handle;
|
||||
}
|
||||
|
||||
public inline function write(data:String):Void{
|
||||
public inline function write(data:String):Void {
|
||||
this.write(data);
|
||||
}
|
||||
|
||||
public inline function writeLine(data:String):Void{
|
||||
public inline function writeLine(data:String):Void {
|
||||
this.writeLine(data);
|
||||
}
|
||||
|
||||
public inline function flush():Void{
|
||||
public inline function flush():Void {
|
||||
this.flush();
|
||||
}
|
||||
|
||||
public inline function close():Void{
|
||||
public inline function close():Void {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
abstract ReadBinaryHandle(FileHandle) from FileHandle {
|
||||
|
||||
public inline function new(handle:FileHandle) {
|
||||
this = handle;
|
||||
}
|
||||
|
||||
public inline function readLine(?withTrailing:Bool = false):Null<String>{
|
||||
public inline function readLine(?withTrailing:Bool = false):Null<String> {
|
||||
return this.readLine(withTrailing);
|
||||
}
|
||||
|
||||
public inline function readAll():Null<String>{
|
||||
public inline function readAll():Null<String> {
|
||||
return this.readAll();
|
||||
}
|
||||
|
||||
public inline function read(count:Int):Null<String>{
|
||||
public inline function read(count:Int):Null<String> {
|
||||
return this.read(count);
|
||||
}
|
||||
|
||||
public inline function readByte():Null<Int>{
|
||||
public inline function readByte():Null<Int> {
|
||||
return this.read();
|
||||
}
|
||||
|
||||
public inline function seek(?whence:BinarySeekWhence = Current, ?offset:Int):Void{
|
||||
this.seek(whence,offset);
|
||||
public inline function seek(?whence:BinarySeekWhence = Current, ?offset:Int):Void {
|
||||
this.seek(whence, offset);
|
||||
}
|
||||
|
||||
public inline function close():Void{
|
||||
public inline function close():Void {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
abstract WriteBinaryHandle(FileHandle) from FileHandle {
|
||||
|
||||
public inline function new(handle:FileHandle) {
|
||||
this = handle;
|
||||
}
|
||||
|
||||
public inline function write(data: String):Void{
|
||||
public inline function write(data:String):Void {
|
||||
this.write(data);
|
||||
}
|
||||
|
||||
// TODO
|
||||
public inline function writeByte(data: Int):Void{
|
||||
public inline function writeByte(data:Int):Void {
|
||||
// this.write(data);
|
||||
}
|
||||
|
||||
public inline function flush():Void{
|
||||
public inline function flush():Void {
|
||||
this.flush();
|
||||
}
|
||||
|
||||
public inline function close():Void{
|
||||
public inline function close():Void {
|
||||
this.close();
|
||||
}
|
||||
|
||||
public inline function seek(?whence:BinarySeekWhence = Current, ?offset:Int):Void{
|
||||
this.seek(whence,offset);
|
||||
public inline function seek(?whence:BinarySeekWhence = Current, ?offset:Int):Void {
|
||||
this.seek(whence, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,9 +19,9 @@ class GPS {
|
||||
private static var shouldDoWholeNumberCheck = true;
|
||||
private static var posAccuracy = 0; // 0 = unkown, 1 = (ins,best guess), 2 = (stored/manual,should be right), 3 = (gps,confirmed)
|
||||
private static var cachedPosition:Pos3;
|
||||
private static var lastPositionResponse: Array<{pos:Pos3,dist:Float}> = [];
|
||||
private static var lastPositionResponse:Array<{pos:Pos3, dist:Float}> = [];
|
||||
|
||||
private static var futureResolve: (pos:Null<Pos3>) -> Void = null;
|
||||
private static var futureResolve:(pos:Null<Pos3>) -> Void = null;
|
||||
|
||||
@:allow(kernel.Init)
|
||||
private static function init() {
|
||||
@ -30,7 +30,7 @@ class GPS {
|
||||
|
||||
public static function setManualPosition(pos:Pos3) {
|
||||
var kvstore = new KVStore("gps");
|
||||
kvstore.set("mpos",pos);
|
||||
kvstore.set("mpos", pos);
|
||||
kvstore.save();
|
||||
|
||||
if (cachedPosition == null) {
|
||||
@ -61,7 +61,7 @@ class GPS {
|
||||
public static function locate():Future<Null<Pos3>> {
|
||||
// TODO: implenet a timeout
|
||||
// TODO: dont send a request twice if the last one is still pending or we moved
|
||||
return new Future<Null<Pos3>>((resolve)->{
|
||||
return new Future<Null<Pos3>>((resolve) -> {
|
||||
futureResolve = resolve;
|
||||
sendPositionRequest();
|
||||
return null;
|
||||
@ -73,10 +73,11 @@ class GPS {
|
||||
}
|
||||
|
||||
private static function persistCachedPositon() {
|
||||
if (cachedPosition == null) return;
|
||||
if (cachedPosition == null)
|
||||
return;
|
||||
var kvstore = new KVStore("gps");
|
||||
|
||||
kvstore.set("cpos",cachedPosition);
|
||||
kvstore.set("cpos", cachedPosition);
|
||||
kvstore.save();
|
||||
}
|
||||
|
||||
@ -94,7 +95,7 @@ class GPS {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPos != null && cPos != null && mPos != cPos){
|
||||
if (mPos != null && cPos != null && mPos != cPos) {
|
||||
// Both are different, so we can use the manual position
|
||||
cachedPosition = mPos;
|
||||
posAccuracy = 1;
|
||||
@ -114,7 +115,6 @@ class GPS {
|
||||
posAccuracy = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static function sendPositionRequest() {
|
||||
@ -122,33 +122,39 @@ class GPS {
|
||||
}
|
||||
|
||||
@:allow(kernel.net.Net)
|
||||
private static function handlePackage(pack:Package<Noise>, dist: Float,iface: INetworkInterface) {
|
||||
private static function handlePackage(pack:Package<Noise>, dist:Float, iface:INetworkInterface) {
|
||||
switch (pack.type) {
|
||||
case GPSRequest:
|
||||
if (!shouldRespond) return;
|
||||
if (posAccuracy < 2) return;
|
||||
if (cachedPosition == null) return;
|
||||
if (!shouldRespond)
|
||||
return;
|
||||
if (posAccuracy < 2)
|
||||
return;
|
||||
if (cachedPosition == null)
|
||||
return;
|
||||
|
||||
var response = new Package(Net.networkID,pack.fromID, pack.msgID, GPSResponse(cachedPosition),null,0);
|
||||
iface.send(pack.fromID,Net.networkID,response);
|
||||
var response = new Package(Net.networkID, pack.fromID, pack.msgID, GPSResponse(cachedPosition), null, 0);
|
||||
iface.send(pack.fromID, Net.networkID, response);
|
||||
case GPSResponse(pos):
|
||||
if (lastPositionResponse.contains({pos:pos,dist:dist})) return; // Ignore duplicate responses
|
||||
if (lastPositionResponse.contains({pos: pos, dist: dist}))
|
||||
return; // Ignore duplicate responses
|
||||
|
||||
lastPositionResponse.push({pos:pos,dist:dist});
|
||||
lastPositionResponse.push({pos: pos, dist: dist});
|
||||
|
||||
// TODO: wait for a few seconds before calculating the position, so we can get more responses
|
||||
|
||||
if (lastPositionResponse.length < 4) return; // We need at least 3 responses to calculate the position
|
||||
if (lastPositionResponse.length < 4)
|
||||
return; // We need at least 3 responses to calculate the position
|
||||
|
||||
var calculatedPosition = calculatePosition();
|
||||
|
||||
if (calculatedPosition != null){
|
||||
if (calculatedPosition != null) {
|
||||
calculatedPosition = calculatedPosition.round();
|
||||
}
|
||||
|
||||
lastPositionResponse = []; // Reset the response array
|
||||
|
||||
if (calculatedPosition == null) return;
|
||||
if (calculatedPosition == null)
|
||||
return;
|
||||
cachedPosition = calculatedPosition;
|
||||
posAccuracy = 3;
|
||||
|
||||
@ -158,7 +164,8 @@ class GPS {
|
||||
}
|
||||
|
||||
private static function calculatePosition():Null<Pos3> {
|
||||
if (lastPositionResponse.length < 3) return null;
|
||||
if (lastPositionResponse.length < 3)
|
||||
return null;
|
||||
|
||||
// do a simple trilateration with the last 3 responses for now
|
||||
var p1 = lastPositionResponse[0].pos;
|
||||
@ -169,13 +176,14 @@ class GPS {
|
||||
var r2 = lastPositionResponse[1].dist;
|
||||
var r3 = lastPositionResponse[2].dist;
|
||||
|
||||
var result = trilateration(p1,p2,p3,r1,r2,r3);
|
||||
var result = trilateration(p1, p2, p3, r1, r2, r3);
|
||||
|
||||
if (result.a.close(result.b)) return result.a;
|
||||
if (result.a.close(result.b))
|
||||
return result.a;
|
||||
|
||||
// If we have more than 3 responses, we can use the 4th response to determine which of the two positions is correct
|
||||
// TODO: if this is a pocket computer we cant use this since it can move freely
|
||||
if (lastPositionResponse.length > 3){
|
||||
if (lastPositionResponse.length > 3) {
|
||||
var err1 = Math.abs(result.a.distance(lastPositionResponse[3].pos) - lastPositionResponse[3].dist);
|
||||
var err2 = Math.abs(result.b.distance(lastPositionResponse[3].pos) - lastPositionResponse[3].dist);
|
||||
|
||||
@ -184,12 +192,15 @@ class GPS {
|
||||
return null; // The two positions are essentially the same, so we cant determine which one is correct
|
||||
}
|
||||
|
||||
if (err1 < err2) return result.a;
|
||||
if (err2 < err1) return result.b;
|
||||
if (err1 < err2)
|
||||
return result.a;
|
||||
if (err2 < err1)
|
||||
return result.b;
|
||||
}
|
||||
|
||||
// last resort, just use the position that is closest to a whole number (whithin a resonable margin of error)
|
||||
if (!shouldDoWholeNumberCheck) return null;
|
||||
if (!shouldDoWholeNumberCheck)
|
||||
return null;
|
||||
|
||||
// TODO: mark the position as not so accurate if we use this method
|
||||
|
||||
@ -208,7 +219,7 @@ class GPS {
|
||||
/**
|
||||
Determines the position(s) of a point given 3 other points and the distance to each of them.
|
||||
**/
|
||||
private static function trilateration(p1:Pos3,p2:Pos3,p3: Pos3,r1:Float,r2:Float,r3:Float):Pair<Pos3,Pos3> {
|
||||
private static function trilateration(p1:Pos3, p2:Pos3, p3:Pos3, r1:Float, r2:Float, r3:Float):Pair<Pos3, Pos3> {
|
||||
var a2b = p2 - p1;
|
||||
var a2c = p3 - p1;
|
||||
|
||||
@ -227,9 +238,9 @@ class GPS {
|
||||
var zSquared = r1 * r1 - x * x - y * y;
|
||||
if (zSquared > 0) {
|
||||
var z = Math.sqrt(zSquared);
|
||||
return new Pair(result + (ez * z),result - (ez * z));
|
||||
return new Pair(result + (ez * z), result - (ez * z));
|
||||
}
|
||||
|
||||
return new Pair(result,result);
|
||||
return new Pair(result, result);
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ import lib.Pos3;
|
||||
using tink.CoreApi;
|
||||
|
||||
class INS {
|
||||
private static var heading: Null<Pos3> = null;
|
||||
private static var alingment: Int = 1; // 0 = degraded, 1 = not aligned, 2 = aligned
|
||||
private static var heading:Null<Pos3> = null;
|
||||
private static var alingment:Int = 1; // 0 = degraded, 1 = not aligned, 2 = aligned
|
||||
|
||||
@:allow(kernel.turtle.Turtle)
|
||||
private static function moveForward() {
|
||||
@ -40,7 +40,8 @@ class INS {
|
||||
|
||||
@:allow(kernel.turtle.Turtle)
|
||||
private static function turnLeft() {
|
||||
if (heading == null) return;
|
||||
if (heading == null)
|
||||
return;
|
||||
if (heading.x == 0 && heading.z == -1) {
|
||||
heading = {x: -1, y: 0, z: 0};
|
||||
} else if (heading.x == -1 && heading.z == 0) {
|
||||
@ -54,7 +55,8 @@ class INS {
|
||||
|
||||
@:allow(kernel.turtle.Turtle)
|
||||
private static function turnRight() {
|
||||
if (heading == null) return;
|
||||
if (heading == null)
|
||||
return;
|
||||
if (heading.x == 0 && heading.z == -1) {
|
||||
heading = {x: 1, y: 0, z: 0};
|
||||
} else if (heading.x == -1 && heading.z == 0) {
|
||||
@ -66,7 +68,7 @@ class INS {
|
||||
}
|
||||
}
|
||||
|
||||
private static function move(dir: Null<Pos3>) {
|
||||
private static function move(dir:Null<Pos3>) {
|
||||
Log.debug('INS move: $dir');
|
||||
var pos = GPS.getPosition();
|
||||
var newPos = pos + dir;
|
||||
@ -77,17 +79,16 @@ class INS {
|
||||
return heading;
|
||||
}
|
||||
|
||||
public static function align(): Promise<Noise> {
|
||||
public static function align():Promise<Noise> {
|
||||
Log.info("Aligning INS");
|
||||
return new Promise<Noise>((resolve,reject)->{
|
||||
|
||||
if (Turtle.instance.getFuelLevel() < 2){
|
||||
return new Promise<Noise>((resolve, reject) -> {
|
||||
if (Turtle.instance.getFuelLevel() < 2) {
|
||||
Log.warn("Not enough fuel to align");
|
||||
reject(new Error("Not enough fuel to align"));
|
||||
return null;
|
||||
}
|
||||
|
||||
GPS.locate().handle((pos1)->{
|
||||
GPS.locate().handle((pos1) -> {
|
||||
Log.debug('pos1: $pos1');
|
||||
if (pos1 == null) {
|
||||
Log.warn("GPS not available for 1st position");
|
||||
@ -103,7 +104,7 @@ class INS {
|
||||
return;
|
||||
}
|
||||
|
||||
GPS.locate().handle((pos2)->{
|
||||
GPS.locate().handle((pos2) -> {
|
||||
Log.debug('pos2: $pos2');
|
||||
if (pos2 == null) {
|
||||
Log.warn("GPS not available for 2nd position");
|
||||
@ -111,7 +112,7 @@ class INS {
|
||||
return;
|
||||
}
|
||||
|
||||
var cHeading = calcHeading(pos1,pos2,moved);
|
||||
var cHeading = calcHeading(pos1, pos2, moved);
|
||||
if (cHeading == null) {
|
||||
Log.error("Can't calculate heading");
|
||||
reject(new Error("Can't calculate heading"));
|
||||
@ -124,7 +125,6 @@ class INS {
|
||||
|
||||
resolve(Noise);
|
||||
});
|
||||
|
||||
});
|
||||
return null;
|
||||
});
|
||||
@ -138,7 +138,7 @@ class INS {
|
||||
return 1;
|
||||
} else {
|
||||
Turtle.instance.turnLeft(); // TODO: Check if successfull
|
||||
if (Turtle.instance.forward().isSuccess()){
|
||||
if (Turtle.instance.forward().isSuccess()) {
|
||||
return 2;
|
||||
} else if (Turtle.instance.back().isSuccess()) {
|
||||
return 3;
|
||||
@ -149,7 +149,7 @@ class INS {
|
||||
}
|
||||
}
|
||||
|
||||
private static function calcHeading(pos1: Pos3,pos2:Pos3,moved:Int): Null<Pos3> {
|
||||
private static function calcHeading(pos1:Pos3, pos2:Pos3, moved:Int):Null<Pos3> {
|
||||
if (moved == 0) {
|
||||
return pos1 - pos2;
|
||||
} else if (moved == 1) {
|
||||
@ -200,5 +200,4 @@ class INS {
|
||||
private static function rotatePos3ToLeft(pos3:Pos3):Pos3 {
|
||||
return rotatePos3ToRight(rotatePos3ToRight(rotatePos3ToRight(pos3)));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,16 +3,15 @@ package kernel.http;
|
||||
using lua.Table;
|
||||
|
||||
class HTTPFailure {
|
||||
|
||||
public final reason:String;
|
||||
public final statusCode:Null<StatusCode>;
|
||||
public final headers:Map<String,String>;
|
||||
public final headers:Map<String, String>;
|
||||
public final body:String;
|
||||
|
||||
@:allow(kernel.http)
|
||||
private function new(failReason: String, ?handle: cc.HTTP.HTTPResponse) {
|
||||
private function new(failReason:String, ?handle:cc.HTTP.HTTPResponse) {
|
||||
this.reason = failReason;
|
||||
if (handle != null){
|
||||
if (handle != null) {
|
||||
this.statusCode = handle.getResponseCode();
|
||||
this.headers = handle.getResponseHeaders().toMap();
|
||||
this.body = handle.readAll();
|
||||
|
@ -6,21 +6,21 @@ using tink.CoreApi;
|
||||
Wrapper for the native HTTP request function.
|
||||
**/
|
||||
class Http {
|
||||
public static function request(url:String,?body:String,?options: String):Future<Outcome<HTTPResponse,HTTPFailure>> {
|
||||
return new Future<Outcome<HTTPResponse,HTTPFailure>>((resolve) -> {
|
||||
KernelEvents.onHttpFailure.handle((params)->{
|
||||
if (params.url == url){
|
||||
resolve(Failure(new HTTPFailure(params.failReason,params.handle)));
|
||||
public static function request(url:String, ?body:String, ?options:String):Future<Outcome<HTTPResponse, HTTPFailure>> {
|
||||
return new Future<Outcome<HTTPResponse, HTTPFailure>>((resolve) -> {
|
||||
KernelEvents.onHttpFailure.handle((params) -> {
|
||||
if (params.url == url) {
|
||||
resolve(Failure(new HTTPFailure(params.failReason, params.handle)));
|
||||
}
|
||||
});
|
||||
|
||||
KernelEvents.onHttpSuccess.handle((params) -> {
|
||||
if (params.url == url){
|
||||
if (params.url == url) {
|
||||
resolve(Success(new HTTPResponse(params.handle)));
|
||||
}
|
||||
});
|
||||
|
||||
cc.HTTP.request(url,body);
|
||||
cc.HTTP.request(url, body);
|
||||
|
||||
return null;
|
||||
});
|
||||
|
@ -3,13 +3,12 @@ package kernel.http;
|
||||
using lua.Table;
|
||||
|
||||
class HTTPResponse {
|
||||
|
||||
public final statusCode:StatusCode;
|
||||
public final headers:Map<String,String>;
|
||||
public final headers:Map<String, String>;
|
||||
public final body:String;
|
||||
|
||||
@:allow(kernel.http)
|
||||
private function new(handle: cc.HTTP.HTTPResponse) {
|
||||
private function new(handle:cc.HTTP.HTTPResponse) {
|
||||
this.statusCode = handle.getResponseCode();
|
||||
this.headers = handle.getResponseHeaders().toMap();
|
||||
this.body = handle.readAll();
|
||||
|
@ -24,28 +24,28 @@ class Log {
|
||||
}
|
||||
|
||||
public static function info(msg:Dynamic, ?pos:haxe.PosInfos) {
|
||||
log({level: Info, message: Std.string(msg),time: 0},pos);
|
||||
log({level: Info, message: Std.string(msg), time: 0}, pos);
|
||||
}
|
||||
|
||||
public static function warn(msg:Dynamic, ?pos:haxe.PosInfos) {
|
||||
log({level: Warn, message: Std.string(msg),time: 0},pos);
|
||||
log({level: Warn, message: Std.string(msg), time: 0}, pos);
|
||||
}
|
||||
|
||||
public static function error(msg:Dynamic, ?pos:haxe.PosInfos) {
|
||||
log({level: Error, message: Std.string(msg),time: 0},pos);
|
||||
log({level: Error, message: Std.string(msg), time: 0}, pos);
|
||||
}
|
||||
|
||||
public static function debug(msg:Dynamic, ?pos:haxe.PosInfos) {
|
||||
#if debug
|
||||
log({level: Debug, message: Std.string(msg),time: 0},pos);
|
||||
log({level: Debug, message: Std.string(msg), time: 0}, pos);
|
||||
#end
|
||||
}
|
||||
|
||||
public static function silly(msg:Dynamic, ?pos:haxe.PosInfos) {
|
||||
log({level: Silly, message: Std.string(msg),time: 0},pos);
|
||||
log({level: Silly, message: Std.string(msg), time: 0}, pos);
|
||||
}
|
||||
|
||||
private static function log(line: LogLine, ?pos:haxe.PosInfos) {
|
||||
private static function log(line:LogLine, ?pos:haxe.PosInfos) {
|
||||
line.origin = pos.className;
|
||||
logLines.push(line);
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package kernel.log;
|
||||
|
||||
typedef LogLine = {
|
||||
level: LogLevel,
|
||||
message: String,
|
||||
time: Int,
|
||||
?origin: String,
|
||||
level:LogLevel,
|
||||
message:String,
|
||||
time:Int,
|
||||
?origin:String,
|
||||
}
|
||||
|
@ -1,18 +1,19 @@
|
||||
package kernel.net;
|
||||
|
||||
import kernel.net.Package.GenericPackage;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
/**
|
||||
A object that is able to send and receive messages.
|
||||
**/
|
||||
interface INetworkInterface {
|
||||
public function listen(chan: Int):Void;
|
||||
public function close(chan: Int):Void;
|
||||
public function isListening(chan: Int): Bool;
|
||||
public function closeAll(): Void;
|
||||
public function send(chan: Int,replyChan: Int,payload: Any):Void;
|
||||
public function listen(chan:Int):Void;
|
||||
public function close(chan:Int):Void;
|
||||
public function isListening(chan:Int):Bool;
|
||||
public function closeAll():Void;
|
||||
public function send(chan:Int, replyChan:Int, payload:Any):Void;
|
||||
public function name():String;
|
||||
public function getBaseRoutingCost():Int;
|
||||
public var onMessage (default, null): Signal<{pack:GenericPackage,?dist:Float}>;
|
||||
public var onMessage(default, null):Signal<{pack:GenericPackage, ?dist:Float}>;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package kernel.net;
|
||||
|
||||
import kernel.net.Package.GenericPackage;
|
||||
import kernel.log.Log;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
/**
|
||||
@ -10,17 +11,17 @@ using tink.CoreApi;
|
||||
class Loopback implements INetworkInterface {
|
||||
public static final instance:Loopback = new Loopback();
|
||||
|
||||
public var onMessage(default, null):Signal<{pack:GenericPackage,dist:Null<Float>}>;
|
||||
public var onMessage(default, null):Signal<{pack:GenericPackage, dist:Null<Float>}>;
|
||||
|
||||
private final onMessageTrigger: SignalTrigger<{pack:GenericPackage,dist:Null<Float>}> = Signal.trigger();
|
||||
private var openChans: Array<Int> = [];
|
||||
private final onMessageTrigger:SignalTrigger<{pack:GenericPackage, dist:Null<Float>}> = Signal.trigger();
|
||||
private var openChans:Array<Int> = [];
|
||||
|
||||
private function new() {
|
||||
this.onMessage = onMessageTrigger.asSignal();
|
||||
}
|
||||
|
||||
public function listen(chan:Int) {
|
||||
if (!this.openChans.contains(chan)){
|
||||
if (!this.openChans.contains(chan)) {
|
||||
this.openChans.push(chan);
|
||||
}
|
||||
}
|
||||
@ -38,9 +39,9 @@ class Loopback implements INetworkInterface {
|
||||
}
|
||||
|
||||
public function send(chan:Int, replyChan:Int, payload:Any) {
|
||||
if (this.openChans.contains(chan)){
|
||||
this.onMessageTrigger.trigger({pack:payload,dist:null});
|
||||
}else{
|
||||
if (this.openChans.contains(chan)) {
|
||||
this.onMessageTrigger.trigger({pack: payload, dist: null});
|
||||
} else {
|
||||
Log.silly("Loopback got package on non open channel");
|
||||
}
|
||||
}
|
||||
|
@ -21,20 +21,21 @@ class Net {
|
||||
Depends on: KernelEvents
|
||||
**/
|
||||
public static inline final BRODCAST_PORT:Int = 65533;
|
||||
|
||||
public static inline final MESSAGE_TIMEOUT:Int = 3;
|
||||
public static inline final DEFAULT_TTL:Int = 10;
|
||||
|
||||
public static final networkID:NetworkID = OS.getComputerID();
|
||||
private static final responseBus:Map<Int, Callback<Outcome<GenericPackage,Error>>> = new Map();
|
||||
private static final responseBus:Map<Int, Callback<Outcome<GenericPackage, Error>>> = new Map();
|
||||
private static final protoHandlers:Map<String, Callback<GenericPackage>> = new Map();
|
||||
private static var interfaces:Array<INetworkInterface>;
|
||||
|
||||
@:allow(kernel.Init)
|
||||
private static function init() {
|
||||
interfaces = [for (e in Peripheral.getAllModems()) e ]; // TODO: is this the way to do it?
|
||||
interfaces = [for (e in Peripheral.getAllModems()) e]; // TODO: is this the way to do it?
|
||||
interfaces.push(Loopback.instance);
|
||||
|
||||
for (interf in interfaces){
|
||||
for (interf in interfaces) {
|
||||
setupInterf(interf);
|
||||
}
|
||||
|
||||
@ -61,8 +62,8 @@ class Net {
|
||||
});
|
||||
}
|
||||
|
||||
private static function setupInterf(interf: INetworkInterface) {
|
||||
interf.onMessage.handle(e -> handle(e.pack,interf,e.dist));
|
||||
private static function setupInterf(interf:INetworkInterface) {
|
||||
interf.onMessage.handle(e -> handle(e.pack, interf, e.dist));
|
||||
interf.listen(networkID);
|
||||
interf.listen(BRODCAST_PORT);
|
||||
}
|
||||
@ -70,8 +71,8 @@ class Net {
|
||||
/**
|
||||
Called when a new package comes in.
|
||||
**/
|
||||
private static function handle(pack:GenericPackage,interf: INetworkInterface, ?dist: Float) {
|
||||
if (pack.toID == networkID || pack.toID == Net.BRODCAST_PORT){
|
||||
private static function handle(pack:GenericPackage, interf:INetworkInterface, ?dist:Float) {
|
||||
if (pack.toID == networkID || pack.toID == Net.BRODCAST_PORT) {
|
||||
switch pack.type {
|
||||
case Data(_) | DataNoResponse(_):
|
||||
// Let a local proccess handle it
|
||||
@ -83,16 +84,16 @@ class Net {
|
||||
}
|
||||
case RouteDiscover(_) | RouteDiscoverResponse(_) | RouteDiscoverUpdate(_):
|
||||
// Delegate to Routing
|
||||
Routing.handleRoutePackage(cast pack,interf);
|
||||
Routing.handleRoutePackage(cast pack, interf);
|
||||
case GPSRequest | GPSResponse(_):
|
||||
if (dist == null) {
|
||||
Log.silly("Got a GPS package but no distance was provided");
|
||||
return;
|
||||
}
|
||||
// Delegate to GPS
|
||||
GPS.handlePackage(cast pack,dist,interf);
|
||||
GPS.handlePackage(cast pack, dist, interf);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
// New message received but its not ment for us. Forward if possible.
|
||||
forwardPackage(pack);
|
||||
}
|
||||
@ -118,13 +119,12 @@ class Net {
|
||||
sendRaw(pack);
|
||||
}
|
||||
|
||||
private static function forwardPackage(pack: GenericPackage) {
|
||||
if (pack.ttl == 0){
|
||||
|
||||
private static function forwardPackage(pack:GenericPackage) {
|
||||
if (pack.ttl == 0) {
|
||||
if (pack.type.match(Data(_))) {
|
||||
// If the package is a data package and the ttl hits 0
|
||||
// we send a "died" message to the sender
|
||||
sendAndForget(pack.fromID, "icmp", {type:"died", msgID: pack.msgID});
|
||||
sendAndForget(pack.fromID, "icmp", {type: "died", msgID: pack.msgID});
|
||||
}
|
||||
|
||||
// Drop package
|
||||
@ -133,7 +133,7 @@ class Net {
|
||||
|
||||
pack.ttl--;
|
||||
|
||||
if (!sendRaw(pack)){
|
||||
if (!sendRaw(pack)) {
|
||||
// Cant forward
|
||||
}
|
||||
}
|
||||
@ -174,13 +174,13 @@ class Net {
|
||||
Just send the package to the right modem.
|
||||
Returns true if message was send
|
||||
**/
|
||||
private static function sendRaw(pack:GenericPackage): Bool {
|
||||
private static function sendRaw(pack:GenericPackage):Bool {
|
||||
var route = Routing.getRouteToID(pack.toID);
|
||||
if (route == null){
|
||||
if (route == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
route.interf.send(route.rep,networkID,pack);
|
||||
route.interf.send(route.rep, networkID, pack);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -200,8 +200,7 @@ class Net {
|
||||
|
||||
var timeout:Timer = null;
|
||||
|
||||
responseBus[pack.msgID] = ((reponse:Outcome<GenericPackage,Error>) -> {
|
||||
|
||||
responseBus[pack.msgID] = ((reponse:Outcome<GenericPackage, Error>) -> {
|
||||
switch reponse {
|
||||
case Success(pack):
|
||||
resolve(pack);
|
||||
@ -217,10 +216,10 @@ class Net {
|
||||
|
||||
timeout = new Timer(MESSAGE_TIMEOUT, () -> {
|
||||
responseBus.remove(pack.msgID);
|
||||
reject(new Error(InternalError,"Message timeout"));
|
||||
reject(new Error(InternalError, "Message timeout"));
|
||||
});
|
||||
|
||||
if (!sendRaw(pack)){
|
||||
if (!sendRaw(pack)) {
|
||||
reject(new Error("ID unreachable"));
|
||||
}
|
||||
|
||||
@ -246,9 +245,9 @@ class Net {
|
||||
/**
|
||||
Sends a ping package to the given id. Returns true if there was a response.
|
||||
**/
|
||||
public static function ping(toID: NetworkID): Promise<Noise> {
|
||||
return new Promise<Noise>((resolve,reject)->{
|
||||
sendAndAwait(toID,"icmp",{type:"ping"}).handle(pack -> {
|
||||
public static function ping(toID:NetworkID):Promise<Noise> {
|
||||
return new Promise<Noise>((resolve, reject) -> {
|
||||
sendAndAwait(toID, "icmp", {type: "ping"}).handle(pack -> {
|
||||
switch pack {
|
||||
case Success(_):
|
||||
resolve(Noise);
|
||||
@ -260,7 +259,7 @@ class Net {
|
||||
});
|
||||
}
|
||||
|
||||
public static function getActiveProtocols(): ReadOnlyArray<String> {
|
||||
public static function getActiveProtocols():ReadOnlyArray<String> {
|
||||
var arr = new Array<String>();
|
||||
|
||||
for (proto in protoHandlers.keys()) {
|
||||
@ -272,7 +271,7 @@ class Net {
|
||||
|
||||
@:allow(kernel.gps.GPS)
|
||||
private static function brodcastGPSRequest() {
|
||||
var pack: Package<Noise> = {
|
||||
var pack:Package<Noise> = {
|
||||
fromID: networkID,
|
||||
toID: Net.BRODCAST_PORT,
|
||||
ttl: 0, // Prevent forwarding
|
||||
@ -282,7 +281,8 @@ class Net {
|
||||
};
|
||||
|
||||
for (modem in Peripheral.getAllModems()) {
|
||||
if (!modem.isWireless()) continue;
|
||||
if (!modem.isWireless())
|
||||
continue;
|
||||
modem.send(Net.BRODCAST_PORT, networkID, pack);
|
||||
}
|
||||
}
|
||||
|
@ -3,15 +3,15 @@ package kernel.net;
|
||||
import lib.Pos3;
|
||||
|
||||
typedef NetworkID = Int;
|
||||
typedef GenericPackage = Package<Dynamic> ;
|
||||
typedef GenericPackage = Package<Dynamic>;
|
||||
|
||||
enum PackageTypes {
|
||||
Data(proto:String);
|
||||
DataNoResponse(proto:String);
|
||||
Response;
|
||||
RouteDiscover(reachableIDs: Array<{id:NetworkID,cost:Int}>);
|
||||
RouteDiscoverResponse(reachableIDs: Array<{id:NetworkID,cost:Int}>);
|
||||
RouteDiscoverUpdate(reachableIDs: Array<{id:NetworkID,cost:Int}>);
|
||||
RouteDiscover(reachableIDs:Array<{id:NetworkID, cost:Int}>);
|
||||
RouteDiscoverResponse(reachableIDs:Array<{id:NetworkID, cost:Int}>);
|
||||
RouteDiscoverUpdate(reachableIDs:Array<{id:NetworkID, cost:Int}>);
|
||||
GPSResponse(pos:Pos3);
|
||||
GPSRequest();
|
||||
}
|
||||
@ -25,7 +25,7 @@ enum PackageTypes {
|
||||
public final msgID:Int;
|
||||
public final type:PackageTypes;
|
||||
public final data:T;
|
||||
public var ttl: Int;
|
||||
public var ttl:Int;
|
||||
|
||||
public function new(fromID:NetworkID, toID:NetworkID, msgID:Int, type:PackageTypes, data:T, ttl:Int) {
|
||||
this.fromID = fromID;
|
||||
|
@ -20,7 +20,6 @@ class Routing {
|
||||
/**
|
||||
Depends on: Peripheral
|
||||
**/
|
||||
|
||||
public static inline final UPDATE_WAIT_TIME:Float = 1;
|
||||
|
||||
public static var onNewNeigbor(default, null):Signal<Int>;
|
||||
|
@ -168,8 +168,7 @@ class BigReactor implements IPeripheral {
|
||||
// getFuelStats
|
||||
// getEnergyStats
|
||||
// getCoolantFluidStats
|
||||
// getHotFluidStats
|
||||
|
||||
// getHotFluidStats
|
||||
// TODO: need research
|
||||
// isMethodAvailable(method: String): Bool
|
||||
// mbGetMaximumCoordinate(): Pos3
|
||||
|
@ -4,47 +4,47 @@ import cc.Peripheral;
|
||||
import kernel.net.Package.NetworkID;
|
||||
|
||||
class Computer implements IPeripheral {
|
||||
public static inline final TYPE_NAME:String = "computer";
|
||||
public static inline final TYPE_NAME:String = "computer";
|
||||
|
||||
private final addr:String;
|
||||
private final addr:String;
|
||||
|
||||
@:allow(kernel.peripherals)
|
||||
private function new(addr: String) {
|
||||
@:allow(kernel.peripherals)
|
||||
private function new(addr:String) {
|
||||
this.addr = addr;
|
||||
}
|
||||
}
|
||||
|
||||
public function getAddr():String {
|
||||
return addr;
|
||||
}
|
||||
|
||||
public function getType():String {
|
||||
public function getType():String {
|
||||
return Computer.TYPE_NAME;
|
||||
}
|
||||
|
||||
public function isOn():Bool {
|
||||
return Peripheral.call(addr, "isOn");
|
||||
}
|
||||
public function isOn():Bool {
|
||||
return Peripheral.call(addr, "isOn");
|
||||
}
|
||||
|
||||
public function getLabel():Null<String> {
|
||||
return Peripheral.call(addr, "getLabel");
|
||||
}
|
||||
public function getLabel():Null<String> {
|
||||
return Peripheral.call(addr, "getLabel");
|
||||
}
|
||||
|
||||
/**
|
||||
Return -1 if no ID set yet
|
||||
**/
|
||||
public function getID():NetworkID{
|
||||
return Peripheral.call(addr, "getID");
|
||||
}
|
||||
/**
|
||||
Return -1 if no ID set yet
|
||||
**/
|
||||
public function getID():NetworkID {
|
||||
return Peripheral.call(addr, "getID");
|
||||
}
|
||||
|
||||
public function reboot() {
|
||||
Peripheral.call(addr, "reboot");
|
||||
}
|
||||
public function reboot() {
|
||||
Peripheral.call(addr, "reboot");
|
||||
}
|
||||
|
||||
public function shutdown() {
|
||||
Peripheral.call(addr, "shutdown");
|
||||
}
|
||||
public function shutdown() {
|
||||
Peripheral.call(addr, "shutdown");
|
||||
}
|
||||
|
||||
public function turnOn() {
|
||||
Peripheral.call(addr, "turnOn");
|
||||
}
|
||||
public function turnOn() {
|
||||
Peripheral.call(addr, "turnOn");
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package kernel.peripherals;
|
||||
|
||||
import cc.Peripheral;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
class Drive implements IPeripheral {
|
||||
@ -15,21 +16,21 @@ class Drive implements IPeripheral {
|
||||
private final onDiskEjectTrigger:SignalTrigger<Noise> = Signal.trigger();
|
||||
|
||||
@:allow(kernel.peripherals)
|
||||
private function new(addr: String) {
|
||||
private function new(addr:String) {
|
||||
this.addr = addr;
|
||||
this.native = Peripheral.wrap(addr);
|
||||
|
||||
this.onDiskInsert = this.onDiskInsertTrigger.asSignal();
|
||||
this.onDiskEject = this.onDiskEjectTrigger.asSignal();
|
||||
|
||||
KernelEvents.onDisk.handle((addr) ->{
|
||||
if (addr == this.addr){
|
||||
KernelEvents.onDisk.handle((addr) -> {
|
||||
if (addr == this.addr) {
|
||||
this.onDiskInsertTrigger.trigger(null);
|
||||
}
|
||||
});
|
||||
|
||||
KernelEvents.onDiskEject.handle((addr)->{
|
||||
if (addr == this.addr){
|
||||
KernelEvents.onDiskEject.handle((addr) -> {
|
||||
if (addr == this.addr) {
|
||||
this.onDiskEjectTrigger.trigger(null);
|
||||
}
|
||||
});
|
||||
@ -43,14 +44,14 @@ class Drive implements IPeripheral {
|
||||
return TYPE_NAME;
|
||||
}
|
||||
|
||||
public inline function isDiskPresent(): Bool {
|
||||
public inline function isDiskPresent():Bool {
|
||||
return this.native.isDiskPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
The label of the disk, or `null` if either no disk is inserted or the disk doesn't have a label.
|
||||
**/
|
||||
public inline function getDiskLabel(): Null<String> {
|
||||
public inline function getDiskLabel():Null<String> {
|
||||
return this.native.getDiskLabel();
|
||||
}
|
||||
|
||||
@ -58,11 +59,11 @@ class Drive implements IPeripheral {
|
||||
this.native.setDiskLabel();
|
||||
}
|
||||
|
||||
public inline function setDiskLabel(label: String): Null<Error> {
|
||||
public inline function setDiskLabel(label:String):Null<Error> {
|
||||
try {
|
||||
this.native.setDiskLabel(label);
|
||||
return null;
|
||||
} catch (e: Dynamic) {
|
||||
} catch (e:Dynamic) {
|
||||
return new Error("Invalid label");
|
||||
}
|
||||
}
|
||||
@ -79,7 +80,7 @@ class Drive implements IPeripheral {
|
||||
return this.getMountPath();
|
||||
}
|
||||
|
||||
public inline function getAudioTitle(): Null<String> {
|
||||
public inline function getAudioTitle():Null<String> {
|
||||
return this.native.getAudioTitle();
|
||||
}
|
||||
|
||||
@ -95,7 +96,7 @@ class Drive implements IPeripheral {
|
||||
this.native.ejectDisk();
|
||||
}
|
||||
|
||||
public inline function getDiskID(): Int {
|
||||
public inline function getDiskID():Int {
|
||||
return this.native.getDiskID();
|
||||
}
|
||||
}
|
||||
|
@ -3,24 +3,24 @@ package kernel.peripherals;
|
||||
import lib.exporter.ExportConfig;
|
||||
import lib.exporter.IExportable;
|
||||
|
||||
class EnergyStorage implements IPeripheral implements IExportable{
|
||||
public static inline final TYPE_NAME:String = "energyCell";
|
||||
class EnergyStorage implements IPeripheral implements IExportable {
|
||||
public static inline final TYPE_NAME:String = "energyCell";
|
||||
|
||||
private final addr:String;
|
||||
private final native: cc.periphs.EnergyStorage;
|
||||
private final addr:String;
|
||||
private final native:cc.periphs.EnergyStorage;
|
||||
|
||||
public function new(addr: String) {
|
||||
this.addr = addr;
|
||||
this.native = cc.Peripheral.wrap(addr);
|
||||
}
|
||||
public function new(addr:String) {
|
||||
this.addr = addr;
|
||||
this.native = cc.Peripheral.wrap(addr);
|
||||
}
|
||||
|
||||
public function getEnergy(): Int {
|
||||
return this.native.getEnergy();
|
||||
}
|
||||
public function getEnergy():Int {
|
||||
return this.native.getEnergy();
|
||||
}
|
||||
|
||||
public function getEnergyCapacity(): Int {
|
||||
return this.native.getEnergyCapacity();
|
||||
}
|
||||
public function getEnergyCapacity():Int {
|
||||
return this.native.getEnergyCapacity();
|
||||
}
|
||||
|
||||
public function getAddr():String {
|
||||
return this.addr;
|
||||
@ -32,10 +32,10 @@ class EnergyStorage implements IPeripheral implements IExportable{
|
||||
|
||||
public function export():ExportConfig {
|
||||
return {
|
||||
getDelegates: [
|
||||
"energy" => _ -> Number(this.getEnergy()),
|
||||
"capacity" => _ -> Number(this.getEnergyCapacity()),
|
||||
],
|
||||
}
|
||||
getDelegates: [
|
||||
"energy" => _ -> Number(this.getEnergy()),
|
||||
"capacity" => _ -> Number(this.getEnergyCapacity()),
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package kernel.peripherals;
|
||||
|
||||
interface IPeripheral {
|
||||
public function getAddr(): String;
|
||||
public function getType(): String;
|
||||
public function getAddr():String;
|
||||
public function getType():String;
|
||||
}
|
||||
|
@ -11,9 +11,9 @@ class Modem implements INetworkInterface implements IPeripheral {
|
||||
public static inline final TYPE_NAME:String = "modem";
|
||||
|
||||
public final addr:String;
|
||||
public var onMessage(default, null):Signal<{pack:GenericPackage,dist:Null<Float>}>;
|
||||
public var onMessage(default, null):Signal<{pack:GenericPackage, dist:Null<Float>}>;
|
||||
|
||||
private final onMessageTrigger:SignalTrigger<{pack:GenericPackage,dist:Null<Float>}> = Signal.trigger();
|
||||
private final onMessageTrigger:SignalTrigger<{pack:GenericPackage, dist:Null<Float>}> = Signal.trigger();
|
||||
private final native:cc.periphs.Modem.Modem;
|
||||
|
||||
@:allow(kernel.peripherals)
|
||||
@ -22,9 +22,9 @@ class Modem implements INetworkInterface implements IPeripheral {
|
||||
this.native = Peripheral.wrap(addr);
|
||||
this.addr = addr;
|
||||
|
||||
KernelEvents.onModemMessage.handle(params ->{
|
||||
try{
|
||||
if (params.addr == this.addr){
|
||||
KernelEvents.onModemMessage.handle(params -> {
|
||||
try {
|
||||
if (params.addr == this.addr) {
|
||||
var pack:GenericPackage = {
|
||||
fromID: params.message.fromID,
|
||||
toID: params.message.toID,
|
||||
@ -36,7 +36,7 @@ class Modem implements INetworkInterface implements IPeripheral {
|
||||
|
||||
this.onMessageTrigger.trigger({pack: pack, dist: params.distance});
|
||||
}
|
||||
}catch(e:Dynamic){
|
||||
} catch (e:Dynamic) {
|
||||
Log.error("Error while parsing modem message");
|
||||
}
|
||||
});
|
||||
@ -79,9 +79,9 @@ class Modem implements INetworkInterface implements IPeripheral {
|
||||
}
|
||||
|
||||
public function getBaseRoutingCost():Int {
|
||||
if (this.native.isWireless()){
|
||||
if (this.native.isWireless()) {
|
||||
return 2; // Prefere messages over cable
|
||||
}else{
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -11,15 +11,15 @@ using tink.CoreApi;
|
||||
Class responseable for retrieving peripherals.
|
||||
**/
|
||||
class Peripheral {
|
||||
public static function getAllAddresses(): Array<String> {
|
||||
public static function getAllAddresses():Array<String> {
|
||||
return cc.Peripheral.getNames().toArray();
|
||||
}
|
||||
|
||||
public static function isPresent(addr: String): Bool {
|
||||
public static function isPresent(addr:String):Bool {
|
||||
return cc.Peripheral.isPresent(addr);
|
||||
}
|
||||
|
||||
public static function getTypes(addr: String): Array<String> {
|
||||
public static function getTypes(addr:String):Array<String> {
|
||||
if (!cc.Peripheral.isPresent(addr)) {
|
||||
return [];
|
||||
}
|
||||
@ -27,11 +27,11 @@ class Peripheral {
|
||||
return cc.Peripheral.getType(addr).toArray();
|
||||
}
|
||||
|
||||
public static function findAddrByType(type: String): Array<String> {
|
||||
public static function findAddrByType(type:String):Array<String> {
|
||||
return getAllAddresses().filter(addr -> getTypes(addr).contains(type));
|
||||
}
|
||||
|
||||
private static function safeGetAddr(addr: String, type: String): Null<String> {
|
||||
|
||||
private static function safeGetAddr(addr:String, type:String):Null<String> {
|
||||
if (!isPresent(addr)) {
|
||||
return null;
|
||||
}
|
||||
@ -44,15 +44,15 @@ class Peripheral {
|
||||
return addr;
|
||||
}
|
||||
|
||||
public static function inspect(addr: String): Null<{ types: Array<String>, methods: Array<String>}> {
|
||||
public static function inspect(addr:String):Null<{types:Array<String>, methods:Array<String>}> {
|
||||
if (!isPresent(addr)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var types = getTypes(addr);
|
||||
var methodsMap = cc.Peripheral.getMethods(addr).toArray();
|
||||
var methods: Array<String> = [];
|
||||
|
||||
var methods:Array<String> = [];
|
||||
|
||||
for (method in methodsMap) {
|
||||
methods.push(method);
|
||||
}
|
||||
@ -67,8 +67,8 @@ class Peripheral {
|
||||
Cast peripheral to a specific type.
|
||||
This is a temporary solution, maybe forever.
|
||||
**/
|
||||
public static function getFromType(addr: String, type: String): Null<IPeripheral> {
|
||||
switch (type){
|
||||
public static function getFromType(addr:String, type:String):Null<IPeripheral> {
|
||||
switch (type) {
|
||||
case Computer.TYPE_NAME:
|
||||
return getComputer(addr);
|
||||
case Screen.TYPE_NAME:
|
||||
@ -88,69 +88,74 @@ class Peripheral {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getScreen(addr: String): Null<Screen> {
|
||||
public static function getScreen(addr:String):Null<Screen> {
|
||||
var addr = safeGetAddr(addr, Screen.TYPE_NAME);
|
||||
if (addr == null) return null;
|
||||
if (addr == null)
|
||||
return null;
|
||||
return new Screen(addr);
|
||||
}
|
||||
|
||||
|
||||
public static function getAllScreens(): Array<Screen> {
|
||||
return [ for (addr in findAddrByType(Screen.TYPE_NAME)) new Screen(addr)];
|
||||
public static function getAllScreens():Array<Screen> {
|
||||
return [for (addr in findAddrByType(Screen.TYPE_NAME)) new Screen(addr)];
|
||||
}
|
||||
|
||||
public static function getModem(addr: String): Null<Modem> {
|
||||
public static function getModem(addr:String):Null<Modem> {
|
||||
var addr = safeGetAddr(addr, Modem.TYPE_NAME);
|
||||
if (addr == null) return null;
|
||||
if (addr == null)
|
||||
return null;
|
||||
return new Modem(addr);
|
||||
}
|
||||
|
||||
public static function getAllModems(): Array<Modem> {
|
||||
return [ for (addr in findAddrByType(Modem.TYPE_NAME)) new Modem(addr)];
|
||||
public static function getAllModems():Array<Modem> {
|
||||
return [for (addr in findAddrByType(Modem.TYPE_NAME)) new Modem(addr)];
|
||||
}
|
||||
|
||||
public static function getDrive(addr: String): Null<Drive> {
|
||||
public static function getDrive(addr:String):Null<Drive> {
|
||||
var addr = safeGetAddr(addr, Drive.TYPE_NAME);
|
||||
if (addr == null) return null;
|
||||
if (addr == null)
|
||||
return null;
|
||||
return new Drive(addr);
|
||||
}
|
||||
|
||||
public static function getAllDrives(): Array<Drive> {
|
||||
return [ for (addr in findAddrByType(Drive.TYPE_NAME)) new Drive(addr)];
|
||||
public static function getAllDrives():Array<Drive> {
|
||||
return [for (addr in findAddrByType(Drive.TYPE_NAME)) new Drive(addr)];
|
||||
}
|
||||
|
||||
public static function getRedstone(side: String): Redstone {
|
||||
public static function getRedstone(side:String):Redstone {
|
||||
// TODO: maybe handle restone differently to not duplicate event listeners
|
||||
return new Redstone(side);
|
||||
}
|
||||
|
||||
public static function getPrinter(addr: String):Null<Printer> {
|
||||
public static function getPrinter(addr:String):Null<Printer> {
|
||||
var addr = safeGetAddr(addr, Printer.TYPE_NAME);
|
||||
if (addr == null) return null;
|
||||
if (addr == null)
|
||||
return null;
|
||||
return new Printer(addr);
|
||||
}
|
||||
|
||||
public static function getAllPrinters(): Array<Printer> {
|
||||
return [ for (addr in findAddrByType(Printer.TYPE_NAME)) new Printer(addr)];
|
||||
public static function getAllPrinters():Array<Printer> {
|
||||
return [for (addr in findAddrByType(Printer.TYPE_NAME)) new Printer(addr)];
|
||||
}
|
||||
|
||||
public static function getEnergyStorage(addr: String): Null<EnergyStorage> {
|
||||
public static function getEnergyStorage(addr:String):Null<EnergyStorage> {
|
||||
var addr = safeGetAddr(addr, EnergyStorage.TYPE_NAME);
|
||||
if (addr == null) return null;
|
||||
if (addr == null)
|
||||
return null;
|
||||
return new EnergyStorage(addr);
|
||||
}
|
||||
|
||||
public static function getAllEnergyStorages(): Array<EnergyStorage> {
|
||||
return [ for (addr in findAddrByType(EnergyStorage.TYPE_NAME)) new EnergyStorage(addr)];
|
||||
public static function getAllEnergyStorages():Array<EnergyStorage> {
|
||||
return [for (addr in findAddrByType(EnergyStorage.TYPE_NAME)) new EnergyStorage(addr)];
|
||||
}
|
||||
|
||||
public static function getComputer(addr: String): Null<Computer> {
|
||||
public static function getComputer(addr:String):Null<Computer> {
|
||||
var addr = safeGetAddr(addr, Computer.TYPE_NAME);
|
||||
if (addr == null) return null;
|
||||
if (addr == null)
|
||||
return null;
|
||||
return new Computer(addr);
|
||||
}
|
||||
|
||||
public static function getAllComputers(): Array<Computer> {
|
||||
return [ for (addr in findAddrByType(Computer.TYPE_NAME)) new Computer(addr)];
|
||||
public static function getAllComputers():Array<Computer> {
|
||||
return [for (addr in findAddrByType(Computer.TYPE_NAME)) new Computer(addr)];
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ class Printer implements IPeripheral {
|
||||
private final native:cc.periphs.Printer.Printer;
|
||||
private final addr:String;
|
||||
|
||||
public function new(addr: String) {
|
||||
public function new(addr:String) {
|
||||
this.native = Peripheral.wrap(addr);
|
||||
this.addr = addr;
|
||||
}
|
||||
@ -23,36 +23,34 @@ class Printer implements IPeripheral {
|
||||
return TYPE_NAME;
|
||||
}
|
||||
|
||||
public function write(text: String){
|
||||
public function write(text:String) {}
|
||||
|
||||
}
|
||||
|
||||
public function getCurserPos(): Pos {
|
||||
public function getCurserPos():Pos {
|
||||
return new Pos({x: 0, y: 0});
|
||||
}
|
||||
|
||||
public function setCurserPos(pos: Pos){
|
||||
public function setCurserPos(pos:Pos) {
|
||||
this.native.setCursorPos(pos.x, pos.y);
|
||||
}
|
||||
|
||||
public function getPageSize(): Rect {
|
||||
public function getPageSize():Rect {
|
||||
var pos = this.native.getPageSize();
|
||||
return new Rect({x: 0, y: 0}, {x: pos.x, y: pos.y});
|
||||
}
|
||||
|
||||
public function newPage(): Bool{
|
||||
public function newPage():Bool {
|
||||
return this.native.newPage();
|
||||
}
|
||||
|
||||
public function endPage(): Bool{
|
||||
public function endPage():Bool {
|
||||
return this.native.endPage();
|
||||
}
|
||||
|
||||
public function setPageTitle(title: String){
|
||||
public function setPageTitle(title:String) {
|
||||
this.native.setPageTitle(title);
|
||||
}
|
||||
|
||||
public function getInkLevel(): Float{
|
||||
public function getInkLevel():Float {
|
||||
return this.native.getInkLevel();
|
||||
}
|
||||
|
||||
|
@ -7,33 +7,33 @@ import lib.Color;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
abstract BundleMask(Int) from cc.Colors.Color to cc.Colors.Color {
|
||||
abstract BundleMask(Int) from cc.Colors.Color to cc.Colors.Color {
|
||||
public inline function new(i:Int) {
|
||||
this = i;
|
||||
}
|
||||
|
||||
@:from
|
||||
public static function fromColor(c: Color) {
|
||||
public static function fromColor(c:Color) {
|
||||
return new BundleMask(c);
|
||||
}
|
||||
|
||||
@:op(A + B)
|
||||
@:op(A | B)
|
||||
public inline function combine(rhs: BundleMask):BundleMask {
|
||||
public inline function combine(rhs:BundleMask):BundleMask {
|
||||
return this | rhs;
|
||||
}
|
||||
|
||||
@:op(A + B)
|
||||
@:op(A | B)
|
||||
public inline function combineWithColor(rhs: Color):BundleMask {
|
||||
public inline function combineWithColor(rhs:Color):BundleMask {
|
||||
return this | rhs;
|
||||
}
|
||||
|
||||
public function getComponents(): ReadOnlyArray<Color> {
|
||||
var components: Array<Color> = [];
|
||||
public function getComponents():ReadOnlyArray<Color> {
|
||||
var components:Array<Color> = [];
|
||||
var mask = 1;
|
||||
for (i in 0...16){
|
||||
if ((this & mask) > 0 ){
|
||||
for (i in 0...16) {
|
||||
if ((this & mask) > 0) {
|
||||
components.push(mask);
|
||||
}
|
||||
mask = mask << 1;
|
||||
@ -57,19 +57,18 @@ class Redstone implements IPeripheral implements IExportable {
|
||||
private var bundleInputState:BundleMask;
|
||||
|
||||
@:allow(kernel.peripherals)
|
||||
private function new(side: Side) {
|
||||
private function new(side:Side) {
|
||||
this.addr = side;
|
||||
this.onChange = this.onChangeTrigger.asSignal();
|
||||
|
||||
updateState();
|
||||
|
||||
KernelEvents.onRedstone.handle(()->{
|
||||
if ((this.getAnalogInput() != this.analogInputState) || (this.bundleInputState != this.getBundledInput())){
|
||||
KernelEvents.onRedstone.handle(() -> {
|
||||
if ((this.getAnalogInput() != this.analogInputState) || (this.bundleInputState != this.getBundledInput())) {
|
||||
updateState();
|
||||
this.onChangeTrigger.trigger(null);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public function getAddr():String {
|
||||
@ -87,35 +86,35 @@ class Redstone implements IPeripheral implements IExportable {
|
||||
|
||||
public inline function setOutput(on:Bool):Void {
|
||||
this.analogInputState = 15;
|
||||
cc.Redstone.setOutput(this.addr,on);
|
||||
cc.Redstone.setOutput(this.addr, on);
|
||||
}
|
||||
|
||||
@export("output")
|
||||
public inline function getOutput(): Bool {
|
||||
public inline function getOutput():Bool {
|
||||
return cc.Redstone.getOutput(this.addr);
|
||||
}
|
||||
|
||||
@export("input")
|
||||
public inline function getInput(): Bool {
|
||||
public inline function getInput():Bool {
|
||||
return cc.Redstone.getInput(this.addr);
|
||||
}
|
||||
|
||||
public inline function setAnalogOutput(strength:Int): Void {
|
||||
public inline function setAnalogOutput(strength:Int):Void {
|
||||
this.analogInputState = strength;
|
||||
cc.Redstone.setAnalogOutput(this.addr,strength);
|
||||
cc.Redstone.setAnalogOutput(this.addr, strength);
|
||||
}
|
||||
|
||||
public inline function getAnalogOutput(): Int {
|
||||
public inline function getAnalogOutput():Int {
|
||||
return cc.Redstone.getAnalogOutput(this.addr);
|
||||
}
|
||||
|
||||
public inline function getAnalogInput(): Int {
|
||||
public inline function getAnalogInput():Int {
|
||||
return cc.Redstone.getAnalogInput(this.addr);
|
||||
}
|
||||
|
||||
public inline function setBundledOutput(output: BundleMask) {
|
||||
public inline function setBundledOutput(output:BundleMask) {
|
||||
this.bundleInputState = output;
|
||||
cc.Redstone.setBundledOutput(this.addr,output);
|
||||
cc.Redstone.setBundledOutput(this.addr, output);
|
||||
}
|
||||
|
||||
public inline function getBundledOutput():BundleMask {
|
||||
@ -126,7 +125,7 @@ class Redstone implements IPeripheral implements IExportable {
|
||||
return cc.Redstone.getBundledInput(this.addr);
|
||||
}
|
||||
|
||||
public inline function testBundledInput(mask: Color): Bool {
|
||||
return cc.Redstone.testBundledInput(this.addr,mask);
|
||||
public inline function testBundledInput(mask:Color):Bool {
|
||||
return cc.Redstone.testBundledInput(this.addr, mask);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ class Screen implements TermWriteable implements IPeripheral {
|
||||
private final nativ:cc.periphs.Monitor.Monitor;
|
||||
private final addr:String;
|
||||
|
||||
private final onResizeTrigger:SignalTrigger<Vec2<Int>> = Signal.trigger();
|
||||
private final onResizeTrigger:SignalTrigger<Vec2<Int>> = Signal.trigger();
|
||||
|
||||
public final onResize:Signal<Vec2<Int>>;
|
||||
|
||||
@ -119,6 +119,6 @@ class Screen implements TermWriteable implements IPeripheral {
|
||||
this.setBackgroundColor(Black);
|
||||
this.setTextColor(White);
|
||||
this.clear();
|
||||
this.setCursorPos(0,0);
|
||||
this.setCursorPos(0, 0);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ enum abstract Side(String) to String {
|
||||
var Back = "back";
|
||||
|
||||
@:from
|
||||
static public function fromString(s: String) {
|
||||
static public function fromString(s:String) {
|
||||
switch (s) {
|
||||
case "top":
|
||||
return Top;
|
||||
|
@ -5,5 +5,5 @@ package kernel.ps;
|
||||
**/
|
||||
@:autoBuild(macros.DCEHack.DCEHack.dceInclude())
|
||||
interface Process {
|
||||
public function run(handle: ProcessHandle): Void;
|
||||
public function run(handle:ProcessHandle):Void;
|
||||
}
|
||||
|
@ -4,32 +4,33 @@ import kernel.ps.ProcessManager.PID;
|
||||
import kernel.ui.WindowContext;
|
||||
import kernel.ui.WindowManager;
|
||||
import haxe.ds.ReadOnlyArray;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
typedef HandleConfig = {
|
||||
?args: Array<String>,
|
||||
?onWrite: Callback<String>,
|
||||
?onExit: Callback<Bool>,
|
||||
?args:Array<String>,
|
||||
?onWrite:Callback<String>,
|
||||
?onExit:Callback<Bool>,
|
||||
}
|
||||
|
||||
class ProcessHandle {
|
||||
public var args(get,null): ReadOnlyArray<String>;
|
||||
public var args(get, null):ReadOnlyArray<String>;
|
||||
|
||||
private final pid: PID;
|
||||
private final pid:PID;
|
||||
private final config:HandleConfig;
|
||||
private final closeFuture: Future<Bool>;
|
||||
private var closeFutureResolev: Bool -> Void;
|
||||
private final windowContexts: Array<WindowContext> = [];
|
||||
private final closeFuture:Future<Bool>;
|
||||
private var closeFutureResolev:Bool->Void;
|
||||
private final windowContexts:Array<WindowContext> = [];
|
||||
private final cbLinks:Array<CallbackLink> = [];
|
||||
private final deferFuncs:Array<Void -> Void> = [];
|
||||
private var hasExited: Bool = false;
|
||||
private final deferFuncs:Array<Void->Void> = [];
|
||||
private var hasExited:Bool = false;
|
||||
|
||||
@:allow(kernel.ps.ProcessManager)
|
||||
private function new(config: HandleConfig,pid: PID) {
|
||||
private function new(config:HandleConfig, pid:PID) {
|
||||
this.config = config;
|
||||
this.pid = pid;
|
||||
|
||||
this.closeFuture = new Future<Bool>((trigger)->{
|
||||
this.closeFuture = new Future<Bool>((trigger) -> {
|
||||
this.closeFutureResolev = trigger;
|
||||
return null;
|
||||
});
|
||||
@ -39,42 +40,45 @@ class ProcessHandle {
|
||||
}
|
||||
}
|
||||
|
||||
public function onExit(): Future<Bool> {
|
||||
public function onExit():Future<Bool> {
|
||||
return this.closeFuture;
|
||||
}
|
||||
|
||||
public function close(success: Bool = true): Void {
|
||||
public function close(success:Bool = true):Void {
|
||||
this.hasExited = true;
|
||||
this.dispose();
|
||||
|
||||
EndOfLoop.endOfLoop(() ->{this.closeFutureResolev(success);});
|
||||
|
||||
EndOfLoop.endOfLoop(() -> {
|
||||
this.closeFutureResolev(success);
|
||||
});
|
||||
ProcessManager.removeProcess(this.pid);
|
||||
}
|
||||
|
||||
public function write(message: String): Void {
|
||||
if (this.hasExited) return;
|
||||
if (this.config.onWrite != null){
|
||||
public function write(message:String):Void {
|
||||
if (this.hasExited)
|
||||
return;
|
||||
if (this.config.onWrite != null) {
|
||||
this.config.onWrite.invoke(message);
|
||||
}
|
||||
}
|
||||
|
||||
public function writeLine(message: String): Void {
|
||||
public function writeLine(message:String):Void {
|
||||
this.write(message + "\n");
|
||||
}
|
||||
|
||||
public function createBufferdWindowContext(): WindowContext {
|
||||
public function createBufferdWindowContext():WindowContext {
|
||||
var ctx = WindowManager.createNewContext();
|
||||
this.windowContexts.push(ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
public function createStatelessWindowContext(): {ctx:WindowContext, setRenderFunc: (() -> Void) -> Void, requestRender:() -> Void} {
|
||||
public function createStatelessWindowContext():{ctx:WindowContext, setRenderFunc:(() -> Void)->Void, requestRender:() -> Void} {
|
||||
var ctx = WindowManager.createNewStatelessContext();
|
||||
this.windowContexts.push(ctx.ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
public function getWindowContexts(): ReadOnlyArray<WindowContext> {
|
||||
public function getWindowContexts():ReadOnlyArray<WindowContext> {
|
||||
return this.windowContexts;
|
||||
}
|
||||
|
||||
@ -88,15 +92,15 @@ class ProcessHandle {
|
||||
}
|
||||
}
|
||||
|
||||
public function getPid(): PID {
|
||||
public function getPid():PID {
|
||||
return this.pid;
|
||||
}
|
||||
|
||||
public function addCallbackLink(link: CallbackLink) {
|
||||
public function addCallbackLink(link:CallbackLink) {
|
||||
this.cbLinks.push(link);
|
||||
}
|
||||
|
||||
public function addDeferFunc(func: Void -> Void) {
|
||||
public function addDeferFunc(func:Void->Void) {
|
||||
this.deferFuncs.push(func);
|
||||
}
|
||||
|
||||
|
@ -8,26 +8,26 @@ using tink.CoreApi;
|
||||
typedef PID = Int;
|
||||
|
||||
class ProcessManager {
|
||||
private static final processList = new Map<PID,ProcessHandle>();
|
||||
private static final processList = new Map<PID, ProcessHandle>();
|
||||
|
||||
public static function run(process:Process, config: HandleConfig):PID {
|
||||
public static function run(process:Process, config:HandleConfig):PID {
|
||||
var pid = createPID();
|
||||
var handle = new ProcessHandle(config, pid);
|
||||
|
||||
|
||||
processList.set(pid, handle);
|
||||
|
||||
try{
|
||||
|
||||
try {
|
||||
process.run(handle);
|
||||
}catch(e:Dynamic){
|
||||
} catch (e:Dynamic) {
|
||||
Log.error("Error while running process: " + e);
|
||||
handle.close(false);
|
||||
}
|
||||
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
public static function kill(pid: PID) {
|
||||
if (!processList.exists(pid)){
|
||||
public static function kill(pid:PID) {
|
||||
if (!processList.exists(pid)) {
|
||||
Log.warn("Trying to kill non-existing process: " + pid);
|
||||
return;
|
||||
}
|
||||
@ -37,7 +37,7 @@ class ProcessManager {
|
||||
handle.close();
|
||||
}
|
||||
|
||||
private static function createPID(): PID {
|
||||
private static function createPID():PID {
|
||||
// TODO: better PID generation
|
||||
|
||||
// generate a random PID
|
||||
@ -45,7 +45,7 @@ class ProcessManager {
|
||||
}
|
||||
|
||||
@:allow(kernel.ui.WindowManager)
|
||||
private static function getProcess(pid:PID):Null<ProcessHandle>{
|
||||
private static function getProcess(pid:PID):Null<ProcessHandle> {
|
||||
return processList.get(pid);
|
||||
}
|
||||
|
||||
|
@ -7,33 +7,32 @@ import kernel.binstore.BinStore;
|
||||
using tink.CoreApi;
|
||||
|
||||
class Service {
|
||||
public final binName:String;
|
||||
public final name:String;
|
||||
public final args:Array<String>;
|
||||
public var pid:PID;
|
||||
public var ps: Process;
|
||||
public final binName:String;
|
||||
public final name:String;
|
||||
public final args:Array<String>;
|
||||
public var pid:PID;
|
||||
public var ps:Process;
|
||||
|
||||
@:allow(kernel.service.ServiceManager)
|
||||
private function new(binName: String,name: String,?args: Array<String> ) {
|
||||
this.binName = binName;
|
||||
this.name = name;
|
||||
this.args = args ?? [];
|
||||
}
|
||||
@:allow(kernel.service.ServiceManager)
|
||||
private function new(binName:String, name:String, ?args:Array<String>) {
|
||||
this.binName = binName;
|
||||
this.name = name;
|
||||
this.args = args ?? [];
|
||||
}
|
||||
|
||||
public function start() {
|
||||
var bin = BinStore.getBinByAlias(this.binName);
|
||||
public function start() {
|
||||
var bin = BinStore.getBinByAlias(this.binName);
|
||||
|
||||
if (bin == null){
|
||||
throw new Error('Bin ${this.binName} not found');
|
||||
}
|
||||
|
||||
this.ps = Type.createInstance(bin.c,this.args);
|
||||
if (bin == null) {
|
||||
throw new Error('Bin ${this.binName} not found');
|
||||
}
|
||||
|
||||
this.pid = ProcessManager.run(this.ps,{});
|
||||
}
|
||||
this.ps = Type.createInstance(bin.c, this.args);
|
||||
|
||||
public function stop() {
|
||||
ProcessManager.kill(this.pid);
|
||||
}
|
||||
this.pid = ProcessManager.run(this.ps, {});
|
||||
}
|
||||
|
||||
public function stop() {
|
||||
ProcessManager.kill(this.pid);
|
||||
}
|
||||
}
|
||||
|
@ -7,135 +7,134 @@ import lib.KVStore;
|
||||
using tink.CoreApi;
|
||||
|
||||
class ServiceManager {
|
||||
private static final services:Map<String,Service> = new Map();
|
||||
private static final services:Map<String, Service> = new Map();
|
||||
|
||||
@:allow(kernel.Init)
|
||||
private static function init() {
|
||||
startAllEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
Add a service to be automatically started.
|
||||
**/
|
||||
public static function enable(name: String) {
|
||||
if (!services.exists(name)){
|
||||
return; // Service must be started
|
||||
}
|
||||
@:allow(kernel.Init)
|
||||
private static function init() {
|
||||
startAllEnabled();
|
||||
}
|
||||
|
||||
var store = KVStore.getStoreForClass();
|
||||
/**
|
||||
Add a service to be automatically started.
|
||||
**/
|
||||
public static function enable(name:String) {
|
||||
if (!services.exists(name)) {
|
||||
return; // Service must be started
|
||||
}
|
||||
|
||||
var enabled = store.get("enabled",[]);
|
||||
enabled.push(name);
|
||||
store.set("enabled",enabled);
|
||||
var store = KVStore.getStoreForClass();
|
||||
|
||||
store.save();
|
||||
}
|
||||
var enabled = store.get("enabled", []);
|
||||
enabled.push(name);
|
||||
store.set("enabled", enabled);
|
||||
|
||||
/**
|
||||
Remove a service from being automatically started.
|
||||
**/
|
||||
private static function disable(name: String) {
|
||||
var store = KVStore.getStoreForClass();
|
||||
var enabled: Array<String> = store.get("enabled");
|
||||
var index = enabled.indexOf(name);
|
||||
if (index == -1){
|
||||
return;
|
||||
}
|
||||
store.save();
|
||||
}
|
||||
|
||||
enabled.splice(index,1);
|
||||
store.save();
|
||||
}
|
||||
/**
|
||||
Remove a service from being automatically started.
|
||||
**/
|
||||
private static function disable(name:String) {
|
||||
var store = KVStore.getStoreForClass();
|
||||
var enabled:Array<String> = store.get("enabled");
|
||||
var index = enabled.indexOf(name);
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
private static function startAllEnabled() {
|
||||
var store = KVStore.getStoreForClass();
|
||||
var enabled: Array<String> = store.get("enabled",[]);
|
||||
for (name in enabled){
|
||||
start(name);
|
||||
}
|
||||
}
|
||||
enabled.splice(index, 1);
|
||||
store.save();
|
||||
}
|
||||
|
||||
private static function load(name: String): Null<Service> {
|
||||
var store = new KVStore('service/${name}');
|
||||
store.load();
|
||||
if (!store.exists("service")){
|
||||
return null;
|
||||
}
|
||||
private static function startAllEnabled() {
|
||||
var store = KVStore.getStoreForClass();
|
||||
var enabled:Array<String> = store.get("enabled", []);
|
||||
for (name in enabled) {
|
||||
start(name);
|
||||
}
|
||||
}
|
||||
|
||||
return store.get("service");
|
||||
}
|
||||
private static function load(name:String):Null<Service> {
|
||||
var store = new KVStore('service/${name}');
|
||||
store.load();
|
||||
if (!store.exists("service")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function register(name: String, binName: String,args: Array<String>): Outcome<Noise,String> {
|
||||
if (BinStore.getBinByAlias(binName) == null){
|
||||
return Failure("bin not found");
|
||||
}
|
||||
return store.get("service");
|
||||
}
|
||||
|
||||
if (load(name) != null){
|
||||
return Failure("service already exists");
|
||||
}
|
||||
public static function register(name:String, binName:String, args:Array<String>):Outcome<Noise, String> {
|
||||
if (BinStore.getBinByAlias(binName) == null) {
|
||||
return Failure("bin not found");
|
||||
}
|
||||
|
||||
var service = new Service(binName,name,args);
|
||||
if (load(name) != null) {
|
||||
return Failure("service already exists");
|
||||
}
|
||||
|
||||
var store = new KVStore('service/${name}');
|
||||
store.set("service",service);
|
||||
store.save();
|
||||
var service = new Service(binName, name, args);
|
||||
|
||||
Log.info('Service ${name} registered');
|
||||
return Success(Noise);
|
||||
}
|
||||
var store = new KVStore('service/${name}');
|
||||
store.set("service", service);
|
||||
store.save();
|
||||
|
||||
public static function unregister(name: String): Outcome<Noise,String> {
|
||||
if (services.exists(name)){
|
||||
return Failure("service is running");
|
||||
}
|
||||
Log.info('Service ${name} registered');
|
||||
return Success(Noise);
|
||||
}
|
||||
|
||||
KVStore.removeNamespace('service/${name}');
|
||||
Log.info('Service ${name} unregistered');
|
||||
return Success(Noise);
|
||||
}
|
||||
|
||||
public static function start(name: String): Outcome<Noise,String> {
|
||||
var service = load(name);
|
||||
if (service == null){
|
||||
return Failure("service not found");
|
||||
}
|
||||
public static function unregister(name:String):Outcome<Noise, String> {
|
||||
if (services.exists(name)) {
|
||||
return Failure("service is running");
|
||||
}
|
||||
|
||||
service.start();
|
||||
services.set(name,service);
|
||||
KVStore.removeNamespace('service/${name}');
|
||||
Log.info('Service ${name} unregistered');
|
||||
return Success(Noise);
|
||||
}
|
||||
|
||||
Log.info('Service ${name} started');
|
||||
return Success(Noise);
|
||||
}
|
||||
public static function start(name:String):Outcome<Noise, String> {
|
||||
var service = load(name);
|
||||
if (service == null) {
|
||||
return Failure("service not found");
|
||||
}
|
||||
|
||||
public static function stop(name: String): Outcome<Noise,String> {
|
||||
if (!services.exists(name)){
|
||||
return Failure("service not found");
|
||||
}
|
||||
service.start();
|
||||
services.set(name, service);
|
||||
|
||||
var service = services.get(name);
|
||||
service.stop();
|
||||
services.remove(name);
|
||||
Log.info('Service ${name} started');
|
||||
return Success(Noise);
|
||||
}
|
||||
|
||||
Log.info('Service ${name} stopped');
|
||||
return Success(Noise);
|
||||
}
|
||||
public static function stop(name:String):Outcome<Noise, String> {
|
||||
if (!services.exists(name)) {
|
||||
return Failure("service not found");
|
||||
}
|
||||
|
||||
public static function listRunning(): Array<String> {
|
||||
var running = [];
|
||||
for (name in services.keys()){
|
||||
running.push(name);
|
||||
}
|
||||
return running;
|
||||
}
|
||||
var service = services.get(name);
|
||||
service.stop();
|
||||
services.remove(name);
|
||||
|
||||
public static function get(name: String): Null<Dynamic> {
|
||||
if (!services.exists(name)){
|
||||
return null;
|
||||
}
|
||||
Log.info('Service ${name} stopped');
|
||||
return Success(Noise);
|
||||
}
|
||||
|
||||
// TODO: Maybe there is a way to check types here?
|
||||
|
||||
var srv = services.get(name);
|
||||
return srv.ps;
|
||||
}
|
||||
public static function listRunning():Array<String> {
|
||||
var running = [];
|
||||
for (name in services.keys()) {
|
||||
running.push(name);
|
||||
}
|
||||
return running;
|
||||
}
|
||||
|
||||
public static function get(name:String):Null<Dynamic> {
|
||||
if (!services.exists(name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: Maybe there is a way to check types here?
|
||||
|
||||
var srv = services.get(name);
|
||||
return srv.ps;
|
||||
}
|
||||
}
|
||||
|
@ -36,42 +36,48 @@ class Turtle {
|
||||
public function forward():Outcome<Noise, String> {
|
||||
var r = cc.Turtle.forward();
|
||||
var r2 = conterToOutcome(r);
|
||||
if (r2.isSuccess()) INS.moveForward();
|
||||
if (r2.isSuccess())
|
||||
INS.moveForward();
|
||||
return r2;
|
||||
}
|
||||
|
||||
public function back():Outcome<Noise, String> {
|
||||
var r = cc.Turtle.back();
|
||||
var r2 = conterToOutcome(r);
|
||||
if (r2.isSuccess()) INS.moveBackward();
|
||||
if (r2.isSuccess())
|
||||
INS.moveBackward();
|
||||
return r2;
|
||||
}
|
||||
|
||||
public function up():Outcome<Noise, String> {
|
||||
var r = cc.Turtle.up();
|
||||
var r2 = conterToOutcome(r);
|
||||
if (r2.isSuccess()) INS.moveUp();
|
||||
if (r2.isSuccess())
|
||||
INS.moveUp();
|
||||
return r2;
|
||||
}
|
||||
|
||||
public function down():Outcome<Noise, String> {
|
||||
var r = cc.Turtle.down();
|
||||
var r2 = conterToOutcome(r);
|
||||
if (r2.isSuccess()) INS.moveDown();
|
||||
if (r2.isSuccess())
|
||||
INS.moveDown();
|
||||
return r2;
|
||||
}
|
||||
|
||||
public function turnLeft():Outcome<Noise, String> {
|
||||
var r = cc.Turtle.turnLeft();
|
||||
var r2 = conterToOutcome(r);
|
||||
if (r2.isSuccess()) INS.turnRight();
|
||||
if (r2.isSuccess())
|
||||
INS.turnRight();
|
||||
return r2;
|
||||
}
|
||||
|
||||
public function turnRight():Outcome<Noise, String> {
|
||||
var r = cc.Turtle.turnRight();
|
||||
var r2 = conterToOutcome(r);
|
||||
if (r2.isSuccess()) INS.turnRight();
|
||||
if (r2.isSuccess())
|
||||
INS.turnRight();
|
||||
return r2;
|
||||
}
|
||||
|
||||
|
@ -103,15 +103,15 @@ class BufferedVirtualTermWriter implements VirtualTermWriter extends TermBuffer
|
||||
}
|
||||
|
||||
public override function getCursorBlink():Bool {
|
||||
if (isEnabled()){
|
||||
if (isEnabled()) {
|
||||
return target.getCursorBlink();
|
||||
}else{
|
||||
} else {
|
||||
return super.getCursorBlink();
|
||||
}
|
||||
}
|
||||
|
||||
public override function setCursorBlink(blink:Bool) {
|
||||
if (isEnabled()){
|
||||
if (isEnabled()) {
|
||||
target.setCursorBlink(blink);
|
||||
}
|
||||
super.setCursorBlink(blink);
|
||||
|
@ -16,12 +16,12 @@ using tink.CoreApi;
|
||||
class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
public var onResize(default, null):Signal<Vec2<Int>>;
|
||||
|
||||
private var onResizeTrigger: SignalTrigger<Vec2<Int>> = Signal.trigger();
|
||||
private var onResizeTrigger:SignalTrigger<Vec2<Int>> = Signal.trigger();
|
||||
private var target:TermWriteable;
|
||||
private var enabled:Bool = false;
|
||||
private var renderFunc:Null<Void->Void> = null;
|
||||
private var renderRequested:Bool = false;
|
||||
private var onResizeLink: CallbackLink;
|
||||
private var onResizeLink:CallbackLink;
|
||||
|
||||
@:allow(kernel.ui)
|
||||
private function new(?target:TermWriteable) {
|
||||
@ -29,7 +29,7 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
setTarget(target);
|
||||
}
|
||||
|
||||
public function setRenderFunc(func: (Void->Void)) {
|
||||
public function setRenderFunc(func:(Void->Void)) {
|
||||
this.renderFunc = func;
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
target.reset();
|
||||
renderFunc();
|
||||
renderRequested = false;
|
||||
}else{
|
||||
} else {
|
||||
renderRequested = true;
|
||||
}
|
||||
}
|
||||
@ -59,7 +59,7 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
|
||||
enabled = true;
|
||||
|
||||
if (renderFunc != null){
|
||||
if (renderFunc != null) {
|
||||
renderFunc();
|
||||
}
|
||||
|
||||
@ -101,11 +101,13 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
//
|
||||
|
||||
public inline function write(text:String) {
|
||||
if (enabled) target.write(text);
|
||||
if (enabled)
|
||||
target.write(text);
|
||||
}
|
||||
|
||||
public inline function scroll(y:Int) {
|
||||
if (enabled) target.scroll(y);
|
||||
if (enabled)
|
||||
target.scroll(y);
|
||||
}
|
||||
|
||||
public inline function getCursorPos():Pos {
|
||||
@ -113,7 +115,8 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
}
|
||||
|
||||
public inline function setCursorPos(x:Int, y:Int) {
|
||||
if (enabled) target.setCursorPos(x, y);
|
||||
if (enabled)
|
||||
target.setCursorPos(x, y);
|
||||
}
|
||||
|
||||
public inline function getCursorBlink():Bool {
|
||||
@ -121,7 +124,8 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
}
|
||||
|
||||
public inline function setCursorBlink(blink:Bool) {
|
||||
if (enabled) target.setCursorBlink(blink);
|
||||
if (enabled)
|
||||
target.setCursorBlink(blink);
|
||||
}
|
||||
|
||||
public inline function getSize():Vec2<Int> {
|
||||
@ -129,11 +133,13 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
}
|
||||
|
||||
public inline function clear() {
|
||||
if (enabled) target.clear();
|
||||
if (enabled)
|
||||
target.clear();
|
||||
}
|
||||
|
||||
public inline function clearLine() {
|
||||
if (enabled) target.clearLine();
|
||||
if (enabled)
|
||||
target.clearLine();
|
||||
}
|
||||
|
||||
public inline function getTextColor():Color {
|
||||
@ -141,7 +147,8 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
}
|
||||
|
||||
public inline function setTextColor(color:Color) {
|
||||
if (enabled) target.setTextColor(color);
|
||||
if (enabled)
|
||||
target.setTextColor(color);
|
||||
}
|
||||
|
||||
public inline function getBackgroundColor():Color {
|
||||
@ -149,7 +156,8 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
}
|
||||
|
||||
public inline function setBackgroundColor(color:Color) {
|
||||
if (enabled) target.setBackgroundColor(color);
|
||||
if (enabled)
|
||||
target.setBackgroundColor(color);
|
||||
}
|
||||
|
||||
public inline function isColor():Bool {
|
||||
@ -157,6 +165,7 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
|
||||
}
|
||||
|
||||
public inline function reset() {
|
||||
if (enabled) target.reset();
|
||||
if (enabled)
|
||||
target.reset();
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class TermBuffer implements TermWriteable {
|
||||
private var cursorPos:Pos = {x: 0, y: 0};
|
||||
private var currentTextColor:Color = White;
|
||||
private var currentBgColor:Color = Black;
|
||||
private var cursorBlink: Bool = false;
|
||||
private var cursorBlink:Bool = false;
|
||||
private var size:Vec2<Int> = {x: 51, y: 19}; // Default size set to default size of the main terminal
|
||||
|
||||
public final onResize:Signal<Vec2<Int>>;
|
||||
@ -178,6 +178,6 @@ class TermBuffer implements TermWriteable {
|
||||
this.setBackgroundColor(Black);
|
||||
this.setTextColor(White);
|
||||
this.clear();
|
||||
this.setCursorPos(0,0);
|
||||
this.setCursorPos(0, 0);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ interface TermWriteable {
|
||||
public function getBackgroundColor():Color;
|
||||
public function setBackgroundColor(color:Color):Void;
|
||||
public function isColor():Bool;
|
||||
|
||||
// public function setPaletteColor(...);
|
||||
// public function getPaletteColor(color);
|
||||
|
||||
|
@ -15,7 +15,7 @@ using tink.CoreApi;
|
||||
class WindowContext implements TermWriteable {
|
||||
private final writer:VirtualTermWriter;
|
||||
|
||||
@:allow(kernel.ui.WindowManager) private var eventDelegate: Null<UIEventDelegate>;
|
||||
@:allow(kernel.ui.WindowManager) private var eventDelegate:Null<UIEventDelegate>;
|
||||
|
||||
public var onClick(default, null):Signal<{button:ButtonType, pos:Pos}>;
|
||||
public var onKey(default, null):Signal<{keyCode:Int, isHeld:Bool}>;
|
||||
@ -145,7 +145,7 @@ class WindowContext implements TermWriteable {
|
||||
Delegate events to an UIEventDelegate.
|
||||
Set to null to stop delegating events.
|
||||
**/
|
||||
public inline function delegateEvents(delegate: Null<UIEventDelegate>){
|
||||
public inline function delegateEvents(delegate:Null<UIEventDelegate>) {
|
||||
this.eventDelegate = delegate;
|
||||
}
|
||||
}
|
||||
|
@ -15,16 +15,17 @@ class WindowManager {
|
||||
Depends on: KernelEvents, Peripheral
|
||||
**/
|
||||
private static var currentMainContext:WindowContext;
|
||||
|
||||
private static final outputMap:Map<String, WindowContext> = new Map();
|
||||
|
||||
@:allow(kernel.Init)
|
||||
private static function init() {
|
||||
KernelEvents.onKey.handle(params -> {
|
||||
if (currentMainContext != null) {
|
||||
if (currentMainContext.eventDelegate != null){
|
||||
if (currentMainContext.eventDelegate != null) {
|
||||
var foo = currentMainContext.eventDelegate.getEventHandlers();
|
||||
foo.onKey != null ? foo.onKey.invoke(params) : null;
|
||||
}else{
|
||||
} else {
|
||||
currentMainContext.onKeyTrigger.trigger(params);
|
||||
}
|
||||
}
|
||||
@ -32,10 +33,10 @@ class WindowManager {
|
||||
|
||||
KernelEvents.onKeyUp.handle(keyCode -> {
|
||||
if (currentMainContext != null) {
|
||||
if (currentMainContext.eventDelegate != null){
|
||||
if (currentMainContext.eventDelegate != null) {
|
||||
var foo = currentMainContext.eventDelegate.getEventHandlers();
|
||||
foo.onKeyUp != null ? foo.onKeyUp.invoke(keyCode) : null;
|
||||
}else{
|
||||
} else {
|
||||
currentMainContext.onKeyUpTrigger.trigger(keyCode);
|
||||
}
|
||||
}
|
||||
@ -43,10 +44,10 @@ class WindowManager {
|
||||
|
||||
KernelEvents.onMouseClick.handle(params -> {
|
||||
if (currentMainContext != null) {
|
||||
if (currentMainContext.eventDelegate != null){
|
||||
if (currentMainContext.eventDelegate != null) {
|
||||
var foo = currentMainContext.eventDelegate.getEventHandlers();
|
||||
foo.onClick != null ? foo.onClick.invoke(params) : null;
|
||||
}else{
|
||||
} else {
|
||||
currentMainContext.onClickTrigger.trigger(params);
|
||||
}
|
||||
}
|
||||
@ -54,10 +55,10 @@ class WindowManager {
|
||||
|
||||
KernelEvents.onMouseDrag.handle(params -> {
|
||||
if (currentMainContext != null) {
|
||||
if (currentMainContext.eventDelegate != null){
|
||||
if (currentMainContext.eventDelegate != null) {
|
||||
var foo = currentMainContext.eventDelegate.getEventHandlers();
|
||||
foo.onMouseDrag != null ? foo.onMouseDrag.invoke(params) : null;
|
||||
}else{
|
||||
} else {
|
||||
currentMainContext.onMouseDragTrigger.trigger(params);
|
||||
}
|
||||
}
|
||||
@ -65,10 +66,10 @@ class WindowManager {
|
||||
|
||||
KernelEvents.onMouseScroll.handle(params -> {
|
||||
if (currentMainContext != null) {
|
||||
if (currentMainContext.eventDelegate != null){
|
||||
if (currentMainContext.eventDelegate != null) {
|
||||
var foo = currentMainContext.eventDelegate.getEventHandlers();
|
||||
foo.onMouseScroll != null ? foo.onMouseScroll.invoke(params) : null;
|
||||
}else{
|
||||
} else {
|
||||
currentMainContext.onMouseScrollTrigger.trigger(params);
|
||||
}
|
||||
}
|
||||
@ -76,10 +77,10 @@ class WindowManager {
|
||||
|
||||
KernelEvents.onMouseUp.handle(params -> {
|
||||
if (currentMainContext != null) {
|
||||
if (currentMainContext.eventDelegate != null){
|
||||
if (currentMainContext.eventDelegate != null) {
|
||||
var foo = currentMainContext.eventDelegate.getEventHandlers();
|
||||
foo.onMouseUp != null ? foo.onMouseUp.invoke(params) : null;
|
||||
}else{
|
||||
} else {
|
||||
currentMainContext.onMouseUpTrigger.trigger(params);
|
||||
}
|
||||
}
|
||||
@ -87,10 +88,10 @@ class WindowManager {
|
||||
|
||||
KernelEvents.onPaste.handle(text -> {
|
||||
if (currentMainContext != null) {
|
||||
if (currentMainContext.eventDelegate != null){
|
||||
if (currentMainContext.eventDelegate != null) {
|
||||
var foo = currentMainContext.eventDelegate.getEventHandlers();
|
||||
foo.onPaste != null ? foo.onPaste.invoke(text) : null;
|
||||
}else{
|
||||
} else {
|
||||
currentMainContext.onPasteTrigger.trigger(text);
|
||||
}
|
||||
}
|
||||
@ -102,10 +103,10 @@ class WindowManager {
|
||||
|
||||
KernelEvents.onChar.handle(char -> {
|
||||
if (currentMainContext != null) {
|
||||
if (currentMainContext.eventDelegate != null){
|
||||
if (currentMainContext.eventDelegate != null) {
|
||||
var foo = currentMainContext.eventDelegate.getEventHandlers();
|
||||
foo.onChar != null ? foo.onChar.invoke(char) : null;
|
||||
}else{
|
||||
} else {
|
||||
currentMainContext.onCharTrigger.trigger(char);
|
||||
}
|
||||
}
|
||||
@ -125,7 +126,7 @@ class WindowManager {
|
||||
return newContext;
|
||||
}
|
||||
|
||||
public static function createNewStatelessContext():{ctx:WindowContext, setRenderFunc:(() -> Void) -> Void, requestRender:Void->Void} {
|
||||
public static function createNewStatelessContext():{ctx:WindowContext, setRenderFunc:(() -> Void)->Void, requestRender:Void->Void} {
|
||||
var writer = new StatelessVirtualTermWriter();
|
||||
var newContext = new WindowContext(writer);
|
||||
|
||||
@ -164,7 +165,7 @@ class WindowManager {
|
||||
context.enable();
|
||||
}
|
||||
|
||||
public static function getContextByPID(pid: PID): ReadOnlyArray<WindowContext> {
|
||||
public static function getContextByPID(pid:PID):ReadOnlyArray<WindowContext> {
|
||||
var handle = ProcessManager.getProcess(pid);
|
||||
if (handle == null) {
|
||||
return [];
|
||||
|
@ -9,7 +9,7 @@ class BuildInfo {
|
||||
**/
|
||||
public static function getGitCommitHash():String {
|
||||
#if !display
|
||||
return CompileTime.buildGitCommitSha();
|
||||
return CompileTime.buildGitCommitSha();
|
||||
#end
|
||||
return "";
|
||||
}
|
||||
|
@ -6,13 +6,13 @@ import kernel.ps.ProcessHandle;
|
||||
using tink.CoreApi;
|
||||
|
||||
abstract class CLIAppBase implements Process {
|
||||
private var handle: ProcessHandle;
|
||||
private var handle:ProcessHandle;
|
||||
|
||||
private final _subcommandsSync: Map<String, (Array<String>) -> Bool> = [];
|
||||
private final _subcommandsAsync: Map<String, (Array<String>) -> Future<Bool>> = [];
|
||||
private final _subcommandsSynopsis: Array<String> = [];
|
||||
private final _subcommandsSync:Map<String, (Array<String>) -> Bool> = [];
|
||||
private final _subcommandsAsync:Map<String, (Array<String>) -> Future<Bool>> = [];
|
||||
private final _subcommandsSynopsis:Array<String> = [];
|
||||
|
||||
public function run(handle: ProcessHandle){
|
||||
public function run(handle:ProcessHandle) {
|
||||
this.handle = handle;
|
||||
|
||||
var subcommand = handle.args[0];
|
||||
@ -35,15 +35,14 @@ abstract class CLIAppBase implements Process {
|
||||
printHelp();
|
||||
return handle.close(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function registerSyncSubcommand(command: String, callback: (Array<String>) -> Bool, synopsis: String = null) {
|
||||
private function registerSyncSubcommand(command:String, callback:(Array<String>) -> Bool, synopsis:String = null) {
|
||||
_subcommandsSync.set(command, callback);
|
||||
_subcommandsSynopsis.push(command + " " + (synopsis ?? ""));
|
||||
}
|
||||
|
||||
private function registerAsyncSubcommand(command: String, callback: (Array<String>) -> Future<Bool>, synopsis: String = null) {
|
||||
private function registerAsyncSubcommand(command:String, callback:(Array<String>) -> Future<Bool>, synopsis:String = null) {
|
||||
_subcommandsAsync.set(command, callback);
|
||||
_subcommandsSynopsis.push(command + " " + (synopsis ?? ""));
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ enum abstract Color(Int) from cc.Colors.Color to cc.Colors.Color {
|
||||
|
||||
@:op(A + B)
|
||||
@:op(A | B)
|
||||
public inline function combine(rhs: Color):BundleMask {
|
||||
public inline function combine(rhs:Color):BundleMask {
|
||||
return this | rhs;
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,10 @@ class Debug {
|
||||
Log.debug("CC/MC version:" + ComputerCraft._HOST);
|
||||
}
|
||||
|
||||
public static function printCanvasToConsole(canvas: Canvas) {
|
||||
var lines: Array<String> = [];
|
||||
public static function printCanvasToConsole(canvas:Canvas) {
|
||||
var lines:Array<String> = [];
|
||||
|
||||
for (pos => pixel in canvas){
|
||||
for (pos => pixel in canvas) {
|
||||
if (lines[pos.y] == null) {
|
||||
lines[pos.y] = "";
|
||||
}
|
||||
@ -38,14 +38,14 @@ class Debug {
|
||||
}
|
||||
|
||||
#if Debug
|
||||
public static function printKernelEventsCount(){
|
||||
public static function printKernelEventsCount() {
|
||||
KernelEvents.printListenerCount();
|
||||
}
|
||||
#end
|
||||
|
||||
#if webconsole
|
||||
public static function printWeb(msg:String) {
|
||||
HTTP.request("http://127.0.0.1:8080/"+Net.networkID,msg);
|
||||
HTTP.request("http://127.0.0.1:8080/" + Net.networkID, msg);
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
@ -25,17 +25,13 @@ class HomeContext {
|
||||
private var ctx:WindowContext = null;
|
||||
private final workspaces:Map<Int, WindowContext> = [];
|
||||
private var currentWorkspace:Int = -1;
|
||||
private var requestRender: Void->Void;
|
||||
private var requestRender:Void->Void;
|
||||
private var renderer:RootElement;
|
||||
|
||||
|
||||
private var selectedOutput:String = "main";
|
||||
private var selectedOutputIndex:Int = -1;
|
||||
|
||||
private final listedApps:Array<String> = [
|
||||
"terminal",
|
||||
"log",
|
||||
"pfclient"
|
||||
];
|
||||
private final listedApps:Array<String> = ["terminal", "log", "pfclient"];
|
||||
|
||||
public function new() {}
|
||||
|
||||
@ -104,7 +100,7 @@ class HomeContext {
|
||||
focusContext(contextId);
|
||||
}
|
||||
|
||||
private function spawnPs(binName: String) {
|
||||
private function spawnPs(binName:String) {
|
||||
var bin = BinStore.getBinByAlias(binName);
|
||||
|
||||
if (bin == null) {
|
||||
@ -112,11 +108,11 @@ class HomeContext {
|
||||
return;
|
||||
}
|
||||
|
||||
var ps = Type.createInstance(bin.c,[]);
|
||||
var ps = Type.createInstance(bin.c, []);
|
||||
var pid = ProcessManager.run(ps, {});
|
||||
var lastContextID = -1;
|
||||
|
||||
for ( ctx in WindowManager.getContextByPID(pid)){
|
||||
for (ctx in WindowManager.getContextByPID(pid)) {
|
||||
lastContextID = addContextNextWorkspace(ctx);
|
||||
}
|
||||
|
||||
@ -141,7 +137,7 @@ class HomeContext {
|
||||
selectedOutput = "main";
|
||||
} else {
|
||||
selectedOutputIndex++;
|
||||
selectedOutput = screenAddr[selectedOutputIndex];
|
||||
selectedOutput = screenAddr[selectedOutputIndex];
|
||||
}
|
||||
|
||||
requestRender();
|
||||
@ -150,21 +146,19 @@ class HomeContext {
|
||||
private function render() {
|
||||
ctx.setCursorBlink(false);
|
||||
|
||||
var workspaceIDs:Array<Int> = [for (k=>v in workspaces) k];
|
||||
var workspaceIDs:Array<Int> = [for (k => v in workspaces) k];
|
||||
workspaceIDs.sort((a, b) -> a - b);
|
||||
|
||||
var children:Array<UIElement> = [
|
||||
for (i in workspaceIDs) new TextElement('Switch to ${i + 1}', {uiEvents: {onClick: this.handleSelectContext.bind(i)}})
|
||||
for (i in workspaceIDs)
|
||||
new TextElement('Switch to ${i + 1}', {uiEvents: {onClick: this.handleSelectContext.bind(i)}})
|
||||
];
|
||||
|
||||
for (i in 0...listedApps.length) {
|
||||
children.push(new TextElement(
|
||||
'Add ${BinStore.getNameByAlias(listedApps[i])}',
|
||||
{uiEvents: {onClick: this.spawnPs.bind(listedApps[i])}}
|
||||
));
|
||||
children.push(new TextElement('Add ${BinStore.getNameByAlias(listedApps[i])}', {uiEvents: {onClick: this.spawnPs.bind(listedApps[i])}}));
|
||||
}
|
||||
|
||||
children.push(new TextElement('Output: ${selectedOutput}',{ uiEvents:{ onClick: this.cycleOutput}}));
|
||||
children.push(new TextElement('Output: ${selectedOutput}', {uiEvents: {onClick: this.cycleOutput}}));
|
||||
children.push(new TextElement('Exit', {style: {bgColor: Red}, uiEvents: {onClick: KernelEvents.shutdown}}));
|
||||
|
||||
renderer.setChildren(children);
|
||||
|
@ -4,8 +4,7 @@ package lib;
|
||||
Represents an item in the game.
|
||||
**/
|
||||
abstract Item(String) to String {
|
||||
|
||||
public inline function new(name: String) {
|
||||
public inline function new(name:String) {
|
||||
// Check if the name is valid. in the format `mod:item_name` e.g. `minecraft:apple`
|
||||
// TODO: implement
|
||||
// make sure to not use regex
|
||||
@ -13,11 +12,11 @@ abstract Item(String) to String {
|
||||
}
|
||||
|
||||
@:from(String)
|
||||
public static function fromString(s: String) {
|
||||
public static function fromString(s:String) {
|
||||
return new Item(s);
|
||||
}
|
||||
|
||||
function getBase(): String {
|
||||
function getBase():String {
|
||||
return this.split(":")[0];
|
||||
}
|
||||
}
|
||||
|
@ -9,15 +9,16 @@ import haxe.ds.StringMap;
|
||||
Key value store with persistence.
|
||||
**/
|
||||
class KVStore {
|
||||
private var kvStore: StringMap<Dynamic> = new StringMap();
|
||||
private var kvStore:StringMap<Dynamic> = new StringMap();
|
||||
|
||||
public final namespace:String;
|
||||
|
||||
public function new(namespace: String) {
|
||||
public function new(namespace:String) {
|
||||
this.namespace = namespace;
|
||||
this.load();
|
||||
}
|
||||
|
||||
public static function removeNamespace(namespace: String): Void {
|
||||
public static function removeNamespace(namespace:String):Void {
|
||||
var nsFile = getNamespaceFile(namespace);
|
||||
FS.delete(nsFile);
|
||||
}
|
||||
@ -27,13 +28,13 @@ class KVStore {
|
||||
return new KVStore(className);
|
||||
}
|
||||
|
||||
private static function getNamespaceFile(namespace: String): String {
|
||||
private static function getNamespaceFile(namespace:String):String {
|
||||
return '/var/ns/$namespace';
|
||||
}
|
||||
|
||||
public function load() {
|
||||
var nsFile = getNamespaceFile(this.namespace);
|
||||
if (FS.exists(nsFile)){
|
||||
if (FS.exists(nsFile)) {
|
||||
var handle = FS.openRead(nsFile);
|
||||
parseFile(handle.readAll());
|
||||
}
|
||||
@ -47,20 +48,20 @@ class KVStore {
|
||||
handle.close();
|
||||
}
|
||||
|
||||
private function parseFile(content: String) {
|
||||
private function parseFile(content:String) {
|
||||
var unserializer = new Unserializer(content);
|
||||
this.kvStore = unserializer.unserialize();
|
||||
}
|
||||
|
||||
public inline function set(key: String, value: Dynamic) {
|
||||
this.kvStore.set(key,value);
|
||||
public inline function set(key:String, value:Dynamic) {
|
||||
this.kvStore.set(key, value);
|
||||
}
|
||||
|
||||
public inline function get<T>(key: String,?orElse:T = null): Null<T> {
|
||||
public inline function get<T>(key:String, ?orElse:T = null):Null<T> {
|
||||
return this.kvStore.get(key) ?? orElse;
|
||||
}
|
||||
|
||||
public inline function exists(key: String): Bool {
|
||||
public inline function exists(key:String):Bool {
|
||||
return this.kvStore.exists(key);
|
||||
}
|
||||
|
||||
@ -68,11 +69,11 @@ class KVStore {
|
||||
this.kvStore.clear();
|
||||
}
|
||||
|
||||
public inline function remove(key: String): Bool {
|
||||
public inline function remove(key:String):Bool {
|
||||
return this.kvStore.remove(key);
|
||||
}
|
||||
|
||||
public inline function keys(): Iterator<String> {
|
||||
public inline function keys():Iterator<String> {
|
||||
return this.kvStore.keys();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package lib;
|
||||
|
||||
class ObjMerge {
|
||||
public static function merge<T>(obj1:T, obj2:T): T {
|
||||
public static function merge<T>(obj1:T, obj2:T):T {
|
||||
if (obj1 == null) {
|
||||
return obj2;
|
||||
}
|
||||
@ -19,6 +19,6 @@ class ObjMerge {
|
||||
}
|
||||
}
|
||||
|
||||
return (rtn:T);
|
||||
return (rtn : T);
|
||||
}
|
||||
}
|
||||
|
@ -6,14 +6,14 @@ import lib.Vec.Vec2;
|
||||
Reporesents a Point in a 2D `Int` System.
|
||||
Basicly a wrapper for Vec2<Int> with some extra functions.
|
||||
**/
|
||||
@:forward(x,y)
|
||||
abstract Pos(Vec2<Int>) from Vec2<Int> to Vec2<Int>{
|
||||
@:forward(x, y)
|
||||
abstract Pos(Vec2<Int>) from Vec2<Int> to Vec2<Int> {
|
||||
inline public function new(i:Vec2<Int>) {
|
||||
this = i;
|
||||
}
|
||||
|
||||
@:op(A + B)
|
||||
public function add(rhs: Vec2<Int>):Pos {
|
||||
public function add(rhs:Vec2<Int>):Pos {
|
||||
return new Pos({
|
||||
y: this.y + rhs.y,
|
||||
x: this.x + rhs.x,
|
||||
@ -21,7 +21,7 @@ abstract Pos(Vec2<Int>) from Vec2<Int> to Vec2<Int>{
|
||||
}
|
||||
|
||||
@:op(A - B)
|
||||
public function sub(rhs: Vec2<Int>):Pos {
|
||||
public function sub(rhs:Vec2<Int>):Pos {
|
||||
return new Pos({
|
||||
y: this.y - rhs.y,
|
||||
x: this.x - rhs.x,
|
||||
@ -29,7 +29,7 @@ abstract Pos(Vec2<Int>) from Vec2<Int> to Vec2<Int>{
|
||||
}
|
||||
|
||||
@:op(A * B)
|
||||
public function multiply(rhs: Vec2<Int>): Pos {
|
||||
public function multiply(rhs:Vec2<Int>):Pos {
|
||||
return new Pos({
|
||||
y: this.y * rhs.y,
|
||||
x: this.x * rhs.x,
|
||||
@ -37,7 +37,7 @@ abstract Pos(Vec2<Int>) from Vec2<Int> to Vec2<Int>{
|
||||
}
|
||||
|
||||
@:op(-A)
|
||||
public function negate(): Pos {
|
||||
public function negate():Pos {
|
||||
return new Pos({
|
||||
y: -this.y,
|
||||
x: -this.x,
|
||||
|
@ -7,14 +7,14 @@ import lib.Vec.Vec3;
|
||||
Basicly a wrapper for Vec3<Float> with some extra functions.
|
||||
`Y` represents the height of the point.
|
||||
**/
|
||||
@:forward(x,y,z)
|
||||
abstract Pos3(Vec3<Float>) from Vec3<Float> to Vec3<Float>{
|
||||
@:forward(x, y, z)
|
||||
abstract Pos3(Vec3<Float>) from Vec3<Float> to Vec3<Float> {
|
||||
inline public function new(i:Vec3<Float>) {
|
||||
this = i;
|
||||
}
|
||||
|
||||
@:op(A + B)
|
||||
public function add(rhs: Vec3<Float>):Pos3 {
|
||||
public function add(rhs:Vec3<Float>):Pos3 {
|
||||
return new Pos3({
|
||||
y: this.y + rhs.y,
|
||||
x: this.x + rhs.x,
|
||||
@ -23,7 +23,7 @@ abstract Pos3(Vec3<Float>) from Vec3<Float> to Vec3<Float>{
|
||||
}
|
||||
|
||||
@:op(A - B)
|
||||
public function sub(rhs: Vec3<Float>):Pos3 {
|
||||
public function sub(rhs:Vec3<Float>):Pos3 {
|
||||
return new Pos3({
|
||||
y: this.y - rhs.y,
|
||||
x: this.x - rhs.x,
|
||||
@ -32,7 +32,7 @@ abstract Pos3(Vec3<Float>) from Vec3<Float> to Vec3<Float>{
|
||||
}
|
||||
|
||||
@:op(A * B)
|
||||
public function multiplyScalar(rhs: Float): Pos3 {
|
||||
public function multiplyScalar(rhs:Float):Pos3 {
|
||||
return new Pos3({
|
||||
y: this.y * rhs,
|
||||
x: this.x * rhs,
|
||||
@ -41,7 +41,7 @@ abstract Pos3(Vec3<Float>) from Vec3<Float> to Vec3<Float>{
|
||||
}
|
||||
|
||||
@:op(A / B)
|
||||
public function divideScalar(rhs: Float): Pos3 {
|
||||
public function divideScalar(rhs:Float):Pos3 {
|
||||
return new Pos3({
|
||||
y: this.y / rhs,
|
||||
x: this.x / rhs,
|
||||
@ -50,7 +50,7 @@ abstract Pos3(Vec3<Float>) from Vec3<Float> to Vec3<Float>{
|
||||
}
|
||||
|
||||
@:op(-A)
|
||||
public function negate(): Pos3 {
|
||||
public function negate():Pos3 {
|
||||
return new Pos3({
|
||||
y: -this.y,
|
||||
x: -this.x,
|
||||
@ -58,11 +58,11 @@ abstract Pos3(Vec3<Float>) from Vec3<Float> to Vec3<Float>{
|
||||
});
|
||||
}
|
||||
|
||||
public function dot(rhs: Vec3<Float>): Float {
|
||||
public function dot(rhs:Vec3<Float>):Float {
|
||||
return this.x * rhs.x + this.y * rhs.y + this.z * rhs.z;
|
||||
}
|
||||
|
||||
public function cross(rhs: Vec3<Float>):Pos3 {
|
||||
public function cross(rhs:Vec3<Float>):Pos3 {
|
||||
return new Pos3({
|
||||
x: this.y * rhs.z - this.z * rhs.y,
|
||||
y: this.z * rhs.x - this.x * rhs.z,
|
||||
|
@ -1,43 +1,42 @@
|
||||
package lib;
|
||||
|
||||
class Rect {
|
||||
|
||||
private final tl:Pos;
|
||||
private final br:Pos;
|
||||
|
||||
public function new(p1: Pos,p2:Pos) {
|
||||
public function new(p1:Pos, p2:Pos) {
|
||||
this.tl = {
|
||||
x: MathI.min(p1.x,p2.x),
|
||||
y: MathI.min(p1.y,p2.y)
|
||||
x: MathI.min(p1.x, p2.x),
|
||||
y: MathI.min(p1.y, p2.y)
|
||||
};
|
||||
|
||||
this.br = {
|
||||
x: MathI.max(p1.x,p2.x),
|
||||
y: MathI.max(p1.y,p2.y)
|
||||
x: MathI.max(p1.x, p2.x),
|
||||
y: MathI.max(p1.y, p2.y)
|
||||
};
|
||||
}
|
||||
|
||||
public function getSize(): Int {
|
||||
public function getSize():Int {
|
||||
return getWidth() * getHight();
|
||||
}
|
||||
|
||||
public function isInside(p: Pos): Bool {
|
||||
public function isInside(p:Pos):Bool {
|
||||
return (p.x >= tl.x && p.x <= br.x) && (p.y >= tl.y && p.y <= br.y);
|
||||
}
|
||||
|
||||
public function isOutside(p: Pos): Bool {
|
||||
public function isOutside(p:Pos):Bool {
|
||||
return !this.isInside(p);
|
||||
}
|
||||
|
||||
public function getHight(): Int {
|
||||
public function getHight():Int {
|
||||
return br.y - tl.y;
|
||||
}
|
||||
|
||||
public function getWidth(): Int {
|
||||
public function getWidth():Int {
|
||||
return br.x - tl.x;
|
||||
}
|
||||
|
||||
public function offset(pos: Pos) {
|
||||
public function offset(pos:Pos) {
|
||||
tl.x += pos.x;
|
||||
tl.y += pos.y;
|
||||
br.x += pos.x;
|
||||
|
@ -12,73 +12,60 @@ import kernel.net.Package.NetworkID;
|
||||
using tink.CoreApi;
|
||||
|
||||
class RessourceNames {
|
||||
public static function get(name: String, controllerID: NetworkID = -1): Promise<Null<NetworkID>> {
|
||||
if (controllerID == -1) controllerID = KernelSettings.siteController;
|
||||
public static function get(name:String, controllerID:NetworkID = -1):Promise<Null<NetworkID>> {
|
||||
if (controllerID == -1)
|
||||
controllerID = KernelSettings.siteController;
|
||||
|
||||
var payload: GetRequest = {name: name, type: "get"};
|
||||
var payload:GetRequest = {name: name, type: "get"};
|
||||
|
||||
return Net.sendAndAwait(
|
||||
controllerID,
|
||||
SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO,
|
||||
payload
|
||||
).map((res)->{
|
||||
switch (res){
|
||||
case Success(pkg):
|
||||
return Success(pkg.data.netID);
|
||||
case Failure(error):
|
||||
return Failure(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
return Net.sendAndAwait(controllerID, SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO, payload).map((res) -> {
|
||||
switch (res) {
|
||||
case Success(pkg):
|
||||
return Success(pkg.data.netID);
|
||||
case Failure(error):
|
||||
return Failure(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function register(name: String, netID: NetworkID, controllerID: NetworkID = -1): Promise<Bool> {
|
||||
if (controllerID == -1) controllerID = KernelSettings.siteController;
|
||||
public static function register(name:String, netID:NetworkID, controllerID:NetworkID = -1):Promise<Bool> {
|
||||
if (controllerID == -1)
|
||||
controllerID = KernelSettings.siteController;
|
||||
|
||||
var payload: RegisterRequest = {name: name, netID: netID, type: "register"};
|
||||
var payload:RegisterRequest = {name: name, netID: netID, type: "register"};
|
||||
|
||||
return Net.sendAndAwait(
|
||||
controllerID,
|
||||
SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO,
|
||||
payload
|
||||
).map((res)->{
|
||||
switch (res){
|
||||
case Success(pkg):
|
||||
return Success(pkg.data.success);
|
||||
case Failure(error):
|
||||
return Failure(error);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
return Net.sendAndAwait(controllerID, SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO, payload).map((res) -> {
|
||||
switch (res) {
|
||||
case Success(pkg):
|
||||
return Success(pkg.data.success);
|
||||
case Failure(error):
|
||||
return Failure(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function unregister(name: String, controllerID: NetworkID = -1): Promise<Noise> {
|
||||
if (controllerID == -1) controllerID = KernelSettings.siteController;
|
||||
public static function unregister(name:String, controllerID:NetworkID = -1):Promise<Noise> {
|
||||
if (controllerID == -1)
|
||||
controllerID = KernelSettings.siteController;
|
||||
|
||||
var payload: UnregisterRequest = {name: name, type: "unregister"};
|
||||
var payload:UnregisterRequest = {name: name, type: "unregister"};
|
||||
|
||||
return Net.sendAndAwait(
|
||||
controllerID,
|
||||
SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO,
|
||||
payload
|
||||
);
|
||||
}
|
||||
return Net.sendAndAwait(controllerID, SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO, payload);
|
||||
}
|
||||
|
||||
public static function list(controllerID: NetworkID = -1): Promise<Array<String>> {
|
||||
if (controllerID == -1) controllerID = KernelSettings.siteController;
|
||||
public static function list(controllerID:NetworkID = -1):Promise<Array<String>> {
|
||||
if (controllerID == -1)
|
||||
controllerID = KernelSettings.siteController;
|
||||
|
||||
var payload: ListRequest = {type: "list"};
|
||||
var payload:ListRequest = {type: "list"};
|
||||
|
||||
return Net.sendAndAwait(
|
||||
controllerID,
|
||||
SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO,
|
||||
payload
|
||||
).map(res->{
|
||||
switch (res){
|
||||
case Success(pkg):
|
||||
return Success(pkg.data);
|
||||
case Failure(error):
|
||||
return Failure(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return Net.sendAndAwait(controllerID, SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO, payload).map(res -> {
|
||||
switch (res) {
|
||||
case Success(pkg):
|
||||
return Success(pkg.data);
|
||||
case Failure(error):
|
||||
return Failure(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -6,41 +6,41 @@ import kernel.log.Log;
|
||||
using tink.CoreApi;
|
||||
|
||||
class Export {
|
||||
private final exportConfig: ExportConfig;
|
||||
private final peripheral: IPeripheral;
|
||||
private final exportConfig:ExportConfig;
|
||||
private final peripheral:IPeripheral;
|
||||
|
||||
public function new<T: IExportable & IPeripheral>(exportPerph: T) {
|
||||
this.peripheral = exportPerph;
|
||||
this.exportConfig = exportPerph.export();
|
||||
}
|
||||
public function new<T:IExportable & IPeripheral>(exportPerph:T) {
|
||||
this.peripheral = exportPerph;
|
||||
this.exportConfig = exportPerph.export();
|
||||
}
|
||||
|
||||
public function handleRequest(req: Request): Response {
|
||||
switch (req.operation){
|
||||
case Get:
|
||||
return handleGet(req);
|
||||
case Set(value):
|
||||
//TODO: implement
|
||||
return NotFound;
|
||||
}
|
||||
}
|
||||
public function handleRequest(req:Request):Response {
|
||||
switch (req.operation) {
|
||||
case Get:
|
||||
return handleGet(req);
|
||||
case Set(value):
|
||||
// TODO: implement
|
||||
return NotFound;
|
||||
}
|
||||
}
|
||||
|
||||
private function handleGet(request: Request): Response {
|
||||
if (!this.exportConfig.getDelegates.exists(request.field)){
|
||||
Log.warn('Requested get field ${request.field} does not exist in ??');
|
||||
return NotFound;
|
||||
}
|
||||
private function handleGet(request:Request):Response {
|
||||
if (!this.exportConfig.getDelegates.exists(request.field)) {
|
||||
Log.warn('Requested get field ${request.field} does not exist in ??');
|
||||
return NotFound;
|
||||
}
|
||||
|
||||
var delegate = this.exportConfig.getDelegates.get(request.field);
|
||||
var value = delegate(request.index);
|
||||
var delegate = this.exportConfig.getDelegates.get(request.field);
|
||||
var value = delegate(request.index);
|
||||
|
||||
return Get(value);
|
||||
}
|
||||
return Get(value);
|
||||
}
|
||||
|
||||
public function getType(): String {
|
||||
return this.peripheral.getType();
|
||||
}
|
||||
public function getType():String {
|
||||
return this.peripheral.getType();
|
||||
}
|
||||
|
||||
public function getAddr(): String {
|
||||
return this.peripheral.getAddr();
|
||||
}
|
||||
public function getAddr():String {
|
||||
return this.peripheral.getAddr();
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,6 @@ package lib.exporter;
|
||||
import lib.exporter.Response;
|
||||
|
||||
typedef ExportConfig = {
|
||||
getDelegates: Map<String, Null<Int>->ValueType>,
|
||||
// setDelegates: Map<String, (ValueType, Null<Int>)->ValueType>,
|
||||
getDelegates:Map<String, Null<Int>->ValueType>,
|
||||
// setDelegates: Map<String, (ValueType, Null<Int>)->ValueType>,
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
package lib.exporter;
|
||||
|
||||
interface IExportable {
|
||||
public function export(): ExportConfig;
|
||||
public function export():ExportConfig;
|
||||
}
|
||||
|
@ -6,23 +6,22 @@ import kernel.net.Package.NetworkID;
|
||||
using tink.CoreApi;
|
||||
|
||||
class Import {
|
||||
public static function get(ressourceLocator: String): Promise<Response> {
|
||||
var request = Request.fromString(ressourceLocator);
|
||||
public static function get(ressourceLocator:String):Promise<Response> {
|
||||
var request = Request.fromString(ressourceLocator);
|
||||
|
||||
return RessourceNames.get(request.id).next((response)->{
|
||||
return performRequest(response,request);
|
||||
});
|
||||
}
|
||||
return RessourceNames.get(request.id).next((response) -> {
|
||||
return performRequest(response, request);
|
||||
});
|
||||
}
|
||||
|
||||
private static function performRequest(netID: NetworkID, request: Request): Promise<Response> {
|
||||
return Net.sendAndAwait(netID,"res",request).map((response)->{
|
||||
switch (response){
|
||||
case Success(data):
|
||||
return Success(cast (data.data, Response));
|
||||
case Failure(error):
|
||||
return Failure(error);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
private static function performRequest(netID:NetworkID, request:Request):Promise<Response> {
|
||||
return Net.sendAndAwait(netID, "res", request).map((response) -> {
|
||||
switch (response) {
|
||||
case Success(data):
|
||||
return Success(cast(data.data, Response));
|
||||
case Failure(error):
|
||||
return Failure(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package lib.exporter;
|
||||
|
||||
enum Operation {
|
||||
Get;
|
||||
Set(value: Dynamic);
|
||||
Get;
|
||||
Set(value:Dynamic);
|
||||
}
|
||||
|
@ -4,48 +4,47 @@ import lua.TableTools;
|
||||
import lua.NativeStringTools;
|
||||
|
||||
class Request {
|
||||
public final id:String;
|
||||
public final field:String;
|
||||
public final index: Null<Int>;
|
||||
public final operation: Operation;
|
||||
public final id:String;
|
||||
public final field:String;
|
||||
public final index:Null<Int>;
|
||||
public final operation:Operation;
|
||||
|
||||
public function new(id:String, field:String, index:Null<Int>, operation:Operation) {
|
||||
this.id = id;
|
||||
this.field = field;
|
||||
this.index = index;
|
||||
this.operation = operation;
|
||||
}
|
||||
public function new(id:String, field:String, index:Null<Int>, operation:Operation) {
|
||||
this.id = id;
|
||||
this.field = field;
|
||||
this.index = index;
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
/**
|
||||
Example:
|
||||
"myfield[2]@myid"
|
||||
"myfield@myid"
|
||||
**/
|
||||
public static function fromString(locator:String):Request {
|
||||
if (StringTools.contains(locator, "[")) {
|
||||
var f = TableTools.pack(NativeStringTools.gmatch(locator, "(%a+)%[([%d]+)%]@(%a+)")());
|
||||
|
||||
/**
|
||||
Example:
|
||||
"myfield[2]@myid"
|
||||
"myfield@myid"
|
||||
**/
|
||||
public static function fromString(locator: String): Request {
|
||||
if (StringTools.contains(locator,"[")){
|
||||
var f = TableTools.pack(NativeStringTools.gmatch(locator, "(%a+)%[([%d]+)%]@(%a+)")());
|
||||
var field = f[1];
|
||||
var index = Std.parseInt(f[2]);
|
||||
var id = f[3];
|
||||
|
||||
var field = f[1];
|
||||
var index = Std.parseInt(f[2]);
|
||||
var id = f[3];
|
||||
return new Request(id, field, index, Get);
|
||||
} else {
|
||||
var f = TableTools.pack(NativeStringTools.gmatch(locator, "(%a+)@(%a+)")());
|
||||
|
||||
return new Request(id, field, index, Get);
|
||||
}else{
|
||||
var f = TableTools.pack(NativeStringTools.gmatch(locator, "(%a+)@(%a+)")());
|
||||
var field = f[1];
|
||||
var id = f[2];
|
||||
|
||||
var field = f[1];
|
||||
var id = f[2];
|
||||
|
||||
return new Request(id, field, null, Get);
|
||||
}
|
||||
}
|
||||
return new Request(id, field, null, Get);
|
||||
}
|
||||
}
|
||||
|
||||
public function toString() {
|
||||
if (index == null){
|
||||
return field + "@" + id;
|
||||
}else{
|
||||
return field + "[" + index + "]@" + id;
|
||||
}
|
||||
}
|
||||
public function toString() {
|
||||
if (index == null) {
|
||||
return field + "@" + id;
|
||||
} else {
|
||||
return field + "[" + index + "]@" + id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
package lib.exporter;
|
||||
|
||||
enum Response {
|
||||
NotFound;
|
||||
Set;
|
||||
NotSet;
|
||||
Get(value: ValueType);
|
||||
NotFound;
|
||||
Set;
|
||||
NotSet;
|
||||
Get(value:ValueType);
|
||||
}
|
||||
|
||||
enum ValueType {
|
||||
Number(value: Int);
|
||||
String(value: String);
|
||||
Bool(value: Bool);
|
||||
Number(value:Int);
|
||||
String(value:String);
|
||||
Bool(value:Bool);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class DummyObservable<T> implements Observable<T> {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function dummy<T>(value: T): Observable<T> {
|
||||
public static function dummy<T>(value:T):Observable<T> {
|
||||
return new DummyObservable<T>(value);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package lib.observable;
|
||||
using tink.CoreApi;
|
||||
|
||||
interface Observable<T> {
|
||||
public function set(value:T): Void;
|
||||
public function set(value:T):Void;
|
||||
public function get():T;
|
||||
public function subscribe(callback:Callback<T>):CallbackLink;
|
||||
}
|
||||
|
@ -1,34 +1,34 @@
|
||||
package lib.observable;
|
||||
|
||||
class ObservableArray<T> extends ObservableValue<Array<T>> {
|
||||
public function new(value: Array<T>) {
|
||||
public function new(value:Array<T>) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
public function insert(pos: Int, x: T):Void {
|
||||
this.value.insert(pos,x);
|
||||
public function insert(pos:Int, x:T):Void {
|
||||
this.value.insert(pos, x);
|
||||
this.callbacks.invoke(this.value);
|
||||
}
|
||||
|
||||
public function pop(): Null<T> {
|
||||
public function pop():Null<T> {
|
||||
var poped = this.pop();
|
||||
this.callbacks.invoke(this.value);
|
||||
return poped;
|
||||
}
|
||||
|
||||
public function push(x: T):Int {
|
||||
public function push(x:T):Int {
|
||||
var i = this.value.push(x);
|
||||
this.callbacks.invoke(this.value);
|
||||
return i;
|
||||
}
|
||||
|
||||
public function remove(x: T): Bool {
|
||||
public function remove(x:T):Bool {
|
||||
var b = this.value.remove(x);
|
||||
this.callbacks.invoke(this.value);
|
||||
return b;
|
||||
}
|
||||
|
||||
public function resize(len: Int) {
|
||||
public function resize(len:Int) {
|
||||
this.value.resize(len);
|
||||
this.callbacks.invoke(this.value);
|
||||
}
|
||||
@ -38,7 +38,7 @@ class ObservableArray<T> extends ObservableValue<Array<T>> {
|
||||
this.callbacks.invoke(this.value);
|
||||
}
|
||||
|
||||
public function shift(): Null<T> {
|
||||
public function shift():Null<T> {
|
||||
var e = this.value.shift();
|
||||
this.callbacks.invoke(this.value);
|
||||
return e;
|
||||
@ -49,7 +49,7 @@ class ObservableArray<T> extends ObservableValue<Array<T>> {
|
||||
this.callbacks.invoke(this.value);
|
||||
}
|
||||
|
||||
public function unshift(x: T):Void {
|
||||
public function unshift(x:T):Void {
|
||||
this.value.unshift(x);
|
||||
this.callbacks.invoke(this.value);
|
||||
}
|
||||
|
@ -7,16 +7,15 @@ import kernel.turtle.Turtle;
|
||||
using tink.CoreApi;
|
||||
|
||||
class TurtleExecuter {
|
||||
|
||||
private var instructions:Array<TurtleInstruction>;
|
||||
|
||||
public function new(instructions:Array<TurtleInstruction>) {
|
||||
this.instructions = instructions;
|
||||
}
|
||||
|
||||
public function getRequiredFuel(): Int {
|
||||
public function getRequiredFuel():Int {
|
||||
var fuel = 0;
|
||||
for(inst in instructions){
|
||||
for (inst in instructions) {
|
||||
if (inst == Forward || inst == Back || inst == Up || inst == Down) {
|
||||
fuel++;
|
||||
}
|
||||
@ -25,9 +24,9 @@ class TurtleExecuter {
|
||||
return fuel;
|
||||
}
|
||||
|
||||
public function getRequiredBlocks(): Int {
|
||||
public function getRequiredBlocks():Int {
|
||||
var blocks = 0;
|
||||
for(inst in instructions){
|
||||
for (inst in instructions) {
|
||||
switch inst {
|
||||
case Place(_):
|
||||
blocks++;
|
||||
@ -42,11 +41,11 @@ class TurtleExecuter {
|
||||
Return the offset of the turtle after executing the instructions.
|
||||
The origin is the starting position of the turtle.
|
||||
**/
|
||||
public function getFinalOffset(): {offset: Pos3, faceing: Pos} {
|
||||
var pos: Pos3 = {x:0, y:0, z:0};
|
||||
var forwardVec: Pos3 = {x: 1, y: 0, z: 0};
|
||||
public function getFinalOffset():{offset:Pos3, faceing:Pos} {
|
||||
var pos:Pos3 = {x: 0, y: 0, z: 0};
|
||||
var forwardVec:Pos3 = {x: 1, y: 0, z: 0};
|
||||
|
||||
for (inst in instructions){
|
||||
for (inst in instructions) {
|
||||
switch inst {
|
||||
case Forward:
|
||||
pos = pos + forwardVec;
|
||||
@ -55,21 +54,21 @@ class TurtleExecuter {
|
||||
case TurnRight:
|
||||
forwardVec = {x: -forwardVec.z, z: forwardVec.x, y: forwardVec.y};
|
||||
case TurnLeft:
|
||||
forwardVec = {x: forwardVec.z, z: -forwardVec.x , y: forwardVec.y};
|
||||
forwardVec = {x: forwardVec.z, z: -forwardVec.x, y: forwardVec.y};
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
return {offset:pos,faceing: new Pos({x:forwardVec.x, y:forwardVec.z})};
|
||||
return {offset: pos, faceing: new Pos({x: forwardVec.x, y: forwardVec.z})};
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
for (inst in instructions){
|
||||
for (inst in instructions) {
|
||||
executeInst(inst);
|
||||
}
|
||||
}
|
||||
|
||||
private function executeInst(instruction: TurtleInstruction): Outcome<Noise,String> {
|
||||
private function executeInst(instruction:TurtleInstruction):Outcome<Noise, String> {
|
||||
switch instruction {
|
||||
case Forward:
|
||||
return Turtle.instance.forward();
|
||||
|
@ -8,11 +8,11 @@ using tink.CoreApi;
|
||||
Extends the Turtle kernel.
|
||||
**/
|
||||
class TurtleExt {
|
||||
public static function getFreeSlots(t: Turtle): Int {
|
||||
var ret: Int = 0;
|
||||
public static function getFreeSlots(t:Turtle):Int {
|
||||
var ret:Int = 0;
|
||||
|
||||
for (i in 0...Turtle.MAX_SLOTS){
|
||||
if (t.getItemCount(i) == 0){
|
||||
for (i in 0...Turtle.MAX_SLOTS) {
|
||||
if (t.getItemCount(i) == 0) {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
@ -20,11 +20,11 @@ class TurtleExt {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static function canPickup(t: Turtle,item: Item): Bool {
|
||||
for (i in 0...Turtle.MAX_SLOTS){
|
||||
public static function canPickup(t:Turtle, item:Item):Bool {
|
||||
for (i in 0...Turtle.MAX_SLOTS) {
|
||||
var slotItem = t.getItemDetail(i).orNull();
|
||||
if (slotItem != null && slotItem.name == item){
|
||||
if (t.getItemSpace(i)>0){
|
||||
if (slotItem != null && slotItem.name == item) {
|
||||
if (t.getItemSpace(i) > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -33,12 +33,12 @@ class TurtleExt {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function canPickupCount(t: Turtle,item: Item): Int {
|
||||
var ret: Int = 0;
|
||||
public static function canPickupCount(t:Turtle, item:Item):Int {
|
||||
var ret:Int = 0;
|
||||
|
||||
for (i in 0...Turtle.MAX_SLOTS){
|
||||
for (i in 0...Turtle.MAX_SLOTS) {
|
||||
var slotItem = Turtle.instance.getItemDetail(i).orNull();
|
||||
if (slotItem != null && slotItem.name == item){
|
||||
if (slotItem != null && slotItem.name == item) {
|
||||
ret += Turtle.instance.getItemSpace(i);
|
||||
}
|
||||
}
|
||||
@ -46,12 +46,12 @@ class TurtleExt {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static function getInventory(t: Turtle): Map<Int,{item: Item, count: Int, free: Int}> {
|
||||
var rtn: Map<Int,{item: Item, count: Int, free: Int}> = new Map();
|
||||
public static function getInventory(t:Turtle):Map<Int, {item:Item, count:Int, free:Int}> {
|
||||
var rtn:Map<Int, {item:Item, count:Int, free:Int}> = new Map();
|
||||
|
||||
for (i in 0...Turtle.MAX_SLOTS){
|
||||
for (i in 0...Turtle.MAX_SLOTS) {
|
||||
var slotItem = t.getItemDetail(i).orNull();
|
||||
if (slotItem != null){
|
||||
if (slotItem != null) {
|
||||
rtn.set(i, {item: slotItem.name, count: slotItem.count, free: t.getItemSpace(i)});
|
||||
}
|
||||
}
|
||||
@ -63,36 +63,30 @@ class TurtleExt {
|
||||
Optimize the turtle inventory.
|
||||
TODO: does not work 100% yet. Can be optimized more i think. Not that it needs to be optimized.
|
||||
**/
|
||||
public static function tidy(t: Turtle) {
|
||||
public static function tidy(t:Turtle) {
|
||||
var inv = getInventory(t);
|
||||
// For each item in the inventory
|
||||
for(k1 => v1 in inv){
|
||||
|
||||
if (v1.free == 0 || v1.count == 0){
|
||||
for (k1 => v1 in inv) {
|
||||
if (v1.free == 0 || v1.count == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(k2 => v2 in inv){
|
||||
|
||||
if (k2 == k1){
|
||||
for (k2 => v2 in inv) {
|
||||
if (k2 == k1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (v1.item == v2.item && v2.free > 0){
|
||||
if (v1.item == v2.item && v2.free > 0) {
|
||||
// We can move an item in there
|
||||
t.transfer(k1,k2,v2.free);
|
||||
t.transfer(k1, k2, v2.free);
|
||||
|
||||
v1.count -= v2.free;
|
||||
if (v1.count <= 0){
|
||||
if (v1.count <= 0) {
|
||||
inv.remove(k1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ enum TurtleInstruction {
|
||||
Down;
|
||||
TurnLeft;
|
||||
TurnRight;
|
||||
Dig(dir: InteractDirections);
|
||||
Place(dir: InteractDirections);
|
||||
PlacseSign(dir: InteractDirections, text: String);
|
||||
Select(slot: TurtleSlot);
|
||||
Dig(dir:InteractDirections);
|
||||
Place(dir:InteractDirections);
|
||||
PlacseSign(dir:InteractDirections, text:String);
|
||||
Select(slot:TurtleSlot);
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package lib.turtle;
|
||||
// Check usage of NativeStringTools
|
||||
// here https://api.haxe.org/lua/NativeStringTools.html
|
||||
// and here http://lua-users.org/wiki/StringLibraryTutorial
|
||||
|
||||
import kernel.turtle.Types.TurtleSlot;
|
||||
import kernel.turtle.Turtle;
|
||||
import lua.NativeStringTools;
|
||||
@ -14,24 +13,21 @@ using tink.CoreApi;
|
||||
Save a set of turtle instructions to a string and execute them.
|
||||
**/
|
||||
class TurtleInstructionParser {
|
||||
public function new() {}
|
||||
|
||||
public function new() {
|
||||
|
||||
}
|
||||
|
||||
public function encode(instructions: Array<TurtleInstruction>): String {
|
||||
public function encode(instructions:Array<TurtleInstruction>):String {
|
||||
var s = "";
|
||||
|
||||
var times = 0;
|
||||
var lastInstruction: TurtleInstruction = null;
|
||||
var lastInstruction:TurtleInstruction = null;
|
||||
|
||||
for (inst in instructions){
|
||||
if (inst == lastInstruction){
|
||||
for (inst in instructions) {
|
||||
if (inst == lastInstruction) {
|
||||
times++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lastInstruction != null){
|
||||
if (lastInstruction != null) {
|
||||
var encoded = encodeInstruction(lastInstruction);
|
||||
s = s + '${times + 1}$encoded';
|
||||
}
|
||||
@ -46,9 +42,9 @@ class TurtleInstructionParser {
|
||||
return s;
|
||||
}
|
||||
|
||||
private function encodeInstruction(inst: TurtleInstruction): String {
|
||||
for (k => v in cmdMap){
|
||||
if (v == inst){
|
||||
private function encodeInstruction(inst:TurtleInstruction):String {
|
||||
for (k => v in cmdMap) {
|
||||
if (v == inst) {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
@ -63,15 +59,15 @@ class TurtleInstructionParser {
|
||||
return "";
|
||||
}
|
||||
|
||||
private function encodeSlot(slot: TurtleSlot): String {
|
||||
private function encodeSlot(slot:TurtleSlot):String {
|
||||
return String.fromCharCode(slot + 97);
|
||||
}
|
||||
|
||||
public function parse(instructionsString: String): Array<TurtleInstruction> {
|
||||
var rtn: Array<TurtleInstruction> = [];
|
||||
var mfunc = NativeStringTools.gmatch(instructionsString,"%d+%D+");
|
||||
public function parse(instructionsString:String):Array<TurtleInstruction> {
|
||||
var rtn:Array<TurtleInstruction> = [];
|
||||
var mfunc = NativeStringTools.gmatch(instructionsString, "%d+%D+");
|
||||
|
||||
while(true){
|
||||
while (true) {
|
||||
var found = mfunc();
|
||||
|
||||
if (found == null) {
|
||||
@ -82,7 +78,7 @@ class TurtleInstructionParser {
|
||||
var command = NativeStringTools.match(found, "%D+");
|
||||
|
||||
var cmd = cmdMap.get(command);
|
||||
if (cmd != null){
|
||||
if (cmd != null) {
|
||||
rtn = rtn.concat([for (i in 0...times) cmd]);
|
||||
}
|
||||
|
||||
@ -96,7 +92,7 @@ class TurtleInstructionParser {
|
||||
return rtn;
|
||||
}
|
||||
|
||||
private static function parseSlot(slot: String): TurtleSlot {
|
||||
private static function parseSlot(slot:String):TurtleSlot {
|
||||
var slot = slot.charCodeAt(0) - 97;
|
||||
|
||||
if (slot < 0 || slot > Turtle.MAX_SLOTS) {
|
||||
@ -107,19 +103,8 @@ class TurtleInstructionParser {
|
||||
return slot;
|
||||
}
|
||||
|
||||
private var cmdMap:Map<String,TurtleInstruction> = [
|
||||
"a" => Forward,
|
||||
"b" => Back,
|
||||
"c" => TurnLeft,
|
||||
"d" => TurnRight,
|
||||
"e" => Up,
|
||||
"f" => Down,
|
||||
"g" => Dig(Front),
|
||||
"h" => Dig(Up),
|
||||
"i" => Dig(Down),
|
||||
"j" => Place(Front),
|
||||
"k" => Place(Up),
|
||||
"l" => Place(Down),
|
||||
private var cmdMap:Map<String, TurtleInstruction> = [
|
||||
"a" => Forward, "b" => Back, "c" => TurnLeft, "d" => TurnRight, "e" => Up, "f" => Down, "g" => Dig(Front), "h" => Dig(Up), "i" => Dig(Down),
|
||||
"j" => Place(Front), "k" => Place(Up), "l" => Place(Down),
|
||||
];
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import lib.Pos;
|
||||
import lib.Rect;
|
||||
import kernel.ui.Pixel;
|
||||
|
||||
abstract Canvas(Array<Array<Pixel>>) to Array<Array<Pixel>> from Array<Array<Pixel>>{
|
||||
abstract Canvas(Array<Array<Pixel>>) to Array<Array<Pixel>> from Array<Array<Pixel>> {
|
||||
inline public function new() {
|
||||
this = [[]];
|
||||
}
|
||||
@ -62,8 +62,8 @@ abstract Canvas(Array<Array<Pixel>>) to Array<Array<Pixel>> from Array<Array<Pix
|
||||
return max;
|
||||
}
|
||||
|
||||
public function getBounds(): Rect {
|
||||
return new Rect({x:0,y:0},{
|
||||
public function getBounds():Rect {
|
||||
return new Rect({x: 0, y: 0}, {
|
||||
x: maxWidth() - 1,
|
||||
y: height() - 1
|
||||
});
|
||||
@ -72,9 +72,9 @@ abstract Canvas(Array<Array<Pixel>>) to Array<Array<Pixel>> from Array<Array<Pix
|
||||
/**
|
||||
Renders the canvas directly to the context
|
||||
**/
|
||||
public function renderToContext(ctx: WindowContext){
|
||||
var lastBgColor: Color = null;
|
||||
var lastTextColor: Color = null;
|
||||
public function renderToContext(ctx:WindowContext) {
|
||||
var lastBgColor:Color = null;
|
||||
var lastTextColor:Color = null;
|
||||
|
||||
for (lineIndex => line in this) {
|
||||
if (line == null || line.length == 0) {
|
||||
@ -126,7 +126,7 @@ abstract Canvas(Array<Array<Pixel>>) to Array<Array<Pixel>> from Array<Array<Pix
|
||||
}
|
||||
|
||||
class CanvasKeyValueIterator {
|
||||
private final canvas:Array<Array<Pixel>> ;
|
||||
private final canvas:Array<Array<Pixel>>;
|
||||
private var index:Null<Pos> = {x: 0, y: 0};
|
||||
private var nextIndex:Null<Pos> = null;
|
||||
|
||||
@ -134,14 +134,14 @@ class CanvasKeyValueIterator {
|
||||
private function new(canvas:Array<Array<Pixel>>) {
|
||||
this.canvas = canvas;
|
||||
|
||||
if (!isValidPos(this.index)){
|
||||
if (!isValidPos(this.index)) {
|
||||
this.index = nextValidPixel();
|
||||
}
|
||||
|
||||
this.nextIndex = nextValidPixel();
|
||||
}
|
||||
|
||||
private function isValidPos(pos: Pos): Bool {
|
||||
private function isValidPos(pos:Pos):Bool {
|
||||
if (this.canvas[pos.y] == null) {
|
||||
return false;
|
||||
}
|
||||
@ -157,19 +157,19 @@ class CanvasKeyValueIterator {
|
||||
return this.index != null;
|
||||
}
|
||||
|
||||
private function nextValidPixel(): Null<Pos> {
|
||||
private function nextValidPixel():Null<Pos> {
|
||||
if (this.index == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var startX = this.index.x + 1;
|
||||
|
||||
for (y in this.index.y...this.canvas.length){
|
||||
for (y in this.index.y...this.canvas.length) {
|
||||
if (this.canvas[y] == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (x in startX...(this.canvas[y].length)){
|
||||
for (x in startX...(this.canvas[y].length)) {
|
||||
if (this.canvas[y][x] == null) {
|
||||
continue;
|
||||
}
|
||||
@ -191,7 +191,6 @@ class CanvasKeyValueIterator {
|
||||
this.index = this.nextIndex;
|
||||
this.nextIndex = nextValidPixel();
|
||||
|
||||
|
||||
return rtn;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,6 @@ package lib.ui;
|
||||
import lib.Color;
|
||||
|
||||
typedef Style = {
|
||||
public var ?fgColor: Color;
|
||||
public var ?bgColor: Color;
|
||||
public var ?fgColor:Color;
|
||||
public var ?bgColor:Color;
|
||||
}
|
||||
|
@ -5,5 +5,5 @@ import kernel.ui.WindowContext;
|
||||
using tink.CoreApi;
|
||||
|
||||
abstract class UIApp {
|
||||
public abstract function invoke(context: WindowContext): Future<Bool>;
|
||||
public abstract function invoke(context:WindowContext):Future<Bool>;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class RootElement implements UIElement {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public function render(bounds: Pos):Canvas {
|
||||
public function render(bounds:Pos):Canvas {
|
||||
var canvas = new Canvas();
|
||||
var offset = new Pos({x: 0, y: 0});
|
||||
|
||||
@ -48,11 +48,11 @@ class RootElement implements UIElement {
|
||||
return canvas;
|
||||
}
|
||||
|
||||
public function setTitle(title: String) {
|
||||
public function setTitle(title:String) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
private inline function hasTitle(): Bool {
|
||||
return title != "";
|
||||
private inline function hasTitle():Bool {
|
||||
return title != "";
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ class TextElement implements UIElement {
|
||||
private final uiEvents:UIEvents;
|
||||
private final style:Style;
|
||||
|
||||
public function new(text:String, ?props: {?style:Style, ?uiEvents:UIEvents}) {
|
||||
public function new(text:String, ?props:{?style:Style, ?uiEvents:UIEvents}) {
|
||||
this.text = text;
|
||||
this.uiEvents = props?.uiEvents;
|
||||
this.style = props?.style ?? {fgColor: White, bgColor: Black};
|
||||
@ -26,7 +26,7 @@ class TextElement implements UIElement {
|
||||
return uiEvents;
|
||||
}
|
||||
|
||||
public function render(bounds: Pos):Canvas {
|
||||
public function render(bounds:Pos):Canvas {
|
||||
var canvas = new Canvas();
|
||||
for (i in 0...this.text.length) {
|
||||
var c = this.text.charAt(i);
|
||||
|
@ -3,5 +3,5 @@ package lib.ui.elements;
|
||||
import lib.ui.rendere.UIEventDelegate;
|
||||
|
||||
interface UIElement extends UIEventDelegate {
|
||||
public function render(bounds: Pos):Canvas;
|
||||
public function render(bounds:Pos):Canvas;
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
package lib.ui.rendere;
|
||||
|
||||
class List implements UIEventDelegate{
|
||||
private final onElementClick: Null<Int->Void>;
|
||||
class List implements UIEventDelegate {
|
||||
private final onElementClick:Null<Int->Void>;
|
||||
|
||||
public function new(?onElementClick: Int->Void) {
|
||||
public function new(?onElementClick:Int->Void) {
|
||||
this.onElementClick = onElementClick;
|
||||
}
|
||||
|
||||
public function render(list:Array<String>): Canvas {
|
||||
public function render(list:Array<String>):Canvas {
|
||||
var canvas = new Canvas();
|
||||
for (line in 0...list.length) {
|
||||
for (char in 0...list[line].length) {
|
||||
@ -22,14 +22,14 @@ class List implements UIEventDelegate{
|
||||
return canvas;
|
||||
}
|
||||
|
||||
public function getEventHandlers(): UIEvents{
|
||||
public function getEventHandlers():UIEvents {
|
||||
return {
|
||||
onClick: handleClick
|
||||
};
|
||||
}
|
||||
|
||||
private function handleClick(e: {button:kernel.ButtonType, pos:Pos}): Void{
|
||||
if (this.onElementClick == null){
|
||||
private function handleClick(e:{button:kernel.ButtonType, pos:Pos}):Void {
|
||||
if (this.onElementClick == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
package lib.ui.rendere;
|
||||
|
||||
interface UIEventDelegate {
|
||||
public function getEventHandlers(): UIEvents;
|
||||
public function getEventHandlers():UIEvents;
|
||||
}
|
||||
|
@ -2,44 +2,43 @@ package macros;
|
||||
|
||||
import haxe.macro.Context;
|
||||
import haxe.macro.Expr;
|
||||
|
||||
using Lambda;
|
||||
|
||||
|
||||
class DCEHack {
|
||||
public static final classes:Array<haxe.macro.Type> = [];
|
||||
|
||||
public static final classes: Array<haxe.macro.Type> = [];
|
||||
|
||||
macro static public function dceInclude(): Array<Field> {
|
||||
#if !display
|
||||
var localClass = Context.getLocalClass();
|
||||
macro static public function dceInclude():Array<Field> {
|
||||
#if !display
|
||||
var localClass = Context.getLocalClass();
|
||||
|
||||
if (localClass == null){
|
||||
return Context.getBuildFields();
|
||||
}
|
||||
if (localClass == null) {
|
||||
return Context.getBuildFields();
|
||||
}
|
||||
|
||||
// Ignore abstract classes
|
||||
if (localClass.get().isAbstract){
|
||||
return Context.getBuildFields();
|
||||
}
|
||||
// Ignore abstract classes
|
||||
if (localClass.get().isAbstract) {
|
||||
return Context.getBuildFields();
|
||||
}
|
||||
|
||||
classes.push(Context.getLocalType());
|
||||
#end
|
||||
return Context.getBuildFields();
|
||||
}
|
||||
classes.push(Context.getLocalType());
|
||||
#end
|
||||
return Context.getBuildFields();
|
||||
}
|
||||
|
||||
macro static public function dceGenerateCreate(){
|
||||
var exprs = [];
|
||||
macro static public function dceGenerateCreate() {
|
||||
var exprs = [];
|
||||
|
||||
for (c in classes){
|
||||
switch (c){
|
||||
case TInst(_.get() => t, _):
|
||||
var path: TypePath = {pack: t.pack, name: t.name};
|
||||
exprs.push(macro new $path());
|
||||
default:
|
||||
Context.error("Unknown type: " + c, Context.currentPos());
|
||||
}
|
||||
}
|
||||
for (c in classes) {
|
||||
switch (c) {
|
||||
case TInst(_.get() => t, _):
|
||||
var path:TypePath = {pack: t.pack, name: t.name};
|
||||
exprs.push(macro new $path());
|
||||
default:
|
||||
Context.error("Unknown type: " + c, Context.currentPos());
|
||||
}
|
||||
}
|
||||
|
||||
return macro return $a{exprs};
|
||||
}
|
||||
return macro return $a{exprs};
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user