Compare commits

...

12 Commits

Author SHA1 Message Date
088fce0aaa made ServiceManager a static class 2023-07-30 15:48:22 +02:00
3b3c69ee56 made GPS and INS a static class 2023-07-30 15:45:30 +02:00
5a9d463192 made GPS a static class 2023-07-30 15:42:02 +02:00
97c906e013 made Net a static class 2023-07-30 15:38:46 +02:00
505d318ffb made Routing a static class 2023-07-30 15:35:43 +02:00
89f209130e made BinStore a static class 2023-07-27 20:45:37 +02:00
74d0232160 made WindowManager a static class 2023-07-27 20:41:23 +02:00
9deea0ee98 made peripherals a static class 2023-07-27 20:38:23 +02:00
a93ee1cddf made Log static class 2023-07-27 20:35:36 +02:00
e1e0180502 changed kernel events to static class 2023-07-27 20:30:39 +02:00
adc5ab1849 makefile watch all files 2023-07-27 20:30:11 +02:00
1a523cb3ce added startup file 2023-07-27 20:15:41 +02:00
44 changed files with 451 additions and 467 deletions

View File

@@ -46,7 +46,7 @@ clean:
.PHONY: watch .PHONY: watch
watch: watch:
find src -name "*.hx" | entr make debug find src | entr make debug
.PHONY: emulator .PHONY: emulator
emulator: emulator:

View File

@@ -26,7 +26,7 @@ import net.Net;
var data = {"foo": "bar"}; var data = {"foo": "bar"};
Net.instance.sendAndAwait(netID,"protoname",data).map((response)->{ Net.sendAndAwait(netID,"protoname",data).map((response)->{
switch (response){ switch (response){
case Success(data): case Success(data):
trace(data); trace(data);
@@ -35,7 +35,7 @@ Net.instance.sendAndAwait(netID,"protoname",data).map((response)->{
} }
}); });
Net.instance.registerProto("res",(pack: GenericPackage)->{ Net.registerProto("res",(pack: GenericPackage)->{
var requestPack: Package<MyType> = cast pack; // Try not to use Dynamic var requestPack: Package<MyType> = cast pack; // Try not to use Dynamic
requestPack.respond("Hello Back"); requestPack.respond("Hello Back");
@@ -54,10 +54,10 @@ Also peripherals can be made accessible via the network. More on that later.
## Usage ## Usage
```haxe ```haxe
var back = Peripheral.instance.getRedstone("back"); var back = Peripheral.getRedstone("back");
back.setOutput(true); back.setOutput(true);
var drive Peripheral.instance.getDrive("drive_0"); var drive Peripheral.getDrive("drive_0");
drive.eject(); drive.eject();
``` ```
@@ -73,7 +73,7 @@ They both can be used just like the [nativ implmentation](https://tweaked.cc/mod
## Usage ## Usage
```haxe ```haxe
var ctx = WindowManager.instance.createNewBufferedContext(); var ctx = WindowManager.createNewBufferedContext();
ctx.setCursorPos(0, 0); ctx.setCursorPos(0, 0);
ctx.setCursorBlink(false); ctx.setCursorBlink(false);
ctx.setBackgroundColor(Blue); ctx.setBackgroundColor(Blue);

View File

@@ -9,7 +9,7 @@ using Lambda;
class Disk extends CLIAppBase { class Disk extends CLIAppBase {
public function new() { public function new() {
registerSyncSubcommand("ls", (args)->{ registerSyncSubcommand("ls", (args)->{
Peripheral.instance.getAllDrives().foreach(drive -> { Peripheral.getAllDrives().foreach(drive -> {
var addr = drive.getAddr(); var addr = drive.getAddr();
var label = drive.getDiskLabel(); var label = drive.getDiskLabel();
var id = drive.getDiskID(); var id = drive.getDiskID();
@@ -53,7 +53,7 @@ class Disk extends CLIAppBase {
} }
var driveAddr = args[0]; var driveAddr = args[0];
var drive = Peripheral.instance.getDrive(driveAddr); var drive = Peripheral.getDrive(driveAddr);
if (drive == null){ if (drive == null){
handle.writeLine("Drive not found: " + driveAddr); handle.writeLine("Drive not found: " + driveAddr);
@@ -76,7 +76,7 @@ class Disk extends CLIAppBase {
} }
var driveAddr = args[0]; var driveAddr = args[0];
var drive = Peripheral.instance.getDrive(driveAddr); var drive = Peripheral.getDrive(driveAddr);
var label:String = args[1]; var label:String = args[1];
if (drive == null){ if (drive == null){
@@ -102,7 +102,7 @@ class Disk extends CLIAppBase {
} }
private function audioDiskPlayPause(driveAddr: String, play: Bool): Bool { private function audioDiskPlayPause(driveAddr: String, play: Bool): Bool {
var drive = Peripheral.instance.getDrive(driveAddr); var drive = Peripheral.getDrive(driveAddr);
if (drive == null){ if (drive == null){
handle.writeLine("Drive not found: " + driveAddr); handle.writeLine("Drive not found: " + driveAddr);

View File

@@ -16,13 +16,13 @@ class GPS extends CLIAppBase {
var pos: Pos3 = new Vec3<Float>(x, y, z); var pos: Pos3 = new Vec3<Float>(x, y, z);
kernel.gps.GPS.instance.setManualPosition(pos); kernel.gps.GPS.setManualPosition(pos);
return true; return true;
},"<x> <y> <z>"); },"<x> <y> <z>");
registerSyncSubcommand("status",(args)->{ registerSyncSubcommand("status",(args)->{
var pos = kernel.gps.GPS.instance.getPosition(); var pos = kernel.gps.GPS.getPosition();
if (pos != null) { if (pos != null) {
handle.writeLine('Position x:${pos.x} y:${pos.y} z:${pos.z}'); handle.writeLine('Position x:${pos.x} y:${pos.y} z:${pos.z}');
} else { } else {
@@ -30,7 +30,7 @@ class GPS extends CLIAppBase {
return true; return true;
} }
var acc = kernel.gps.GPS.instance.getAccuracy(); var acc = kernel.gps.GPS.getAccuracy();
if (acc == 1){ if (acc == 1){
handle.writeLine("Accuracy: Low"); handle.writeLine("Accuracy: Low");
} else if (acc == 2){ } else if (acc == 2){
@@ -39,7 +39,7 @@ class GPS extends CLIAppBase {
handle.writeLine("Accuracy: High"); handle.writeLine("Accuracy: High");
} }
var ins = INS.instance.getHeading(); var ins = INS.getHeading();
if (ins != null) { if (ins != null) {
handle.writeLine('INS heading: ${ins.x} y:${ins.y} z:${ins.z}'); handle.writeLine('INS heading: ${ins.x} y:${ins.y} z:${ins.z}');
} else { } else {
@@ -50,7 +50,7 @@ class GPS extends CLIAppBase {
}); });
registerAsyncSubcommand("locate",(args)->{ registerAsyncSubcommand("locate",(args)->{
return kernel.gps.GPS.instance.locate().map((pos)->{ return kernel.gps.GPS.locate().map((pos)->{
if (pos != null) { if (pos != null) {
handle.writeLine('Position x:${pos.x} y:${pos.y} z:${pos.z}'); handle.writeLine('Position x:${pos.x} y:${pos.y} z:${pos.z}');
} else { } else {
@@ -61,7 +61,7 @@ class GPS extends CLIAppBase {
}); });
registerAsyncSubcommand("ins",(args)->{ registerAsyncSubcommand("ins",(args)->{
return INS.instance.align().map((_)->{ return INS.align().map((_)->{
handle.writeLine("INS aligned"); handle.writeLine("INS aligned");
return true; return true;
}); });

View File

@@ -7,7 +7,7 @@ class ID implements Process {
public function new() {} public function new() {}
public function run(handle:ProcessHandle) { public function run(handle:ProcessHandle) {
handle.writeLine("ID: " + kernel.net.Net.instance.networkID); handle.writeLine("ID: " + kernel.net.Net.networkID);
handle.close(); handle.close();
} }
} }

View File

@@ -24,7 +24,7 @@ class KernelLog implements Process {
statelessCtx.setRenderFunc(this.render); statelessCtx.setRenderFunc(this.render);
Log.instance.onLog.handle(()->{ Log.onLog.handle(()->{
statelessCtx.requestRender(); statelessCtx.requestRender();
}); });
} }
@@ -33,7 +33,7 @@ class KernelLog implements Process {
ctx.clear(); ctx.clear();
ctx.setCursorPos(0,0); ctx.setCursorPos(0,0);
var lines = Log.instance.getLines(); var lines = Log.getLines();
var height = ctx.getSize().y; var height = ctx.getSize().y;
var start = MathI.max(lines.length - height,0); var start = MathI.max(lines.length - height,0);

View File

@@ -9,7 +9,7 @@ using tink.CoreApi;
class Net extends CLIAppBase { class Net extends CLIAppBase {
public function new() { public function new() {
registerSyncSubcommand("route", (args)->{ registerSyncSubcommand("route", (args)->{
var routes = Routing.instance.getRouteTable(); var routes = Routing.getRouteTable();
for(k => v in routes) { for(k => v in routes) {
handle.writeLine('${k} => ${v.interf.name()}(${v.cost})'); handle.writeLine('${k} => ${v.interf.name()}(${v.cost})');
@@ -19,7 +19,7 @@ class Net extends CLIAppBase {
}); });
registerSyncSubcommand("iface", (args)->{ registerSyncSubcommand("iface", (args)->{
var modems = Peripheral.instance.getAllModems(); var modems = Peripheral.getAllModems();
for (modem in modems) { for (modem in modems) {
handle.writeLine(modem.name()); handle.writeLine(modem.name());
@@ -29,7 +29,7 @@ class Net extends CLIAppBase {
}); });
registerSyncSubcommand("proto",(args)->{ registerSyncSubcommand("proto",(args)->{
var protos = kernel.net.Net.instance.getActiveProtocols(); var protos = kernel.net.Net.getActiveProtocols();
for (proto in protos) { for (proto in protos) {
handle.writeLine(proto); handle.writeLine(proto);
@@ -50,7 +50,7 @@ class Net extends CLIAppBase {
return Future.sync(false); return Future.sync(false);
} }
return kernel.net.Net.instance.ping(toID).map(result -> { return kernel.net.Net.ping(toID).map(result -> {
switch (result){ switch (result){
case Success(_): case Success(_):
handle.write("Ping succeeded"); handle.write("Ping succeeded");

View File

@@ -8,7 +8,7 @@ class Perf extends CLIAppBase {
registerSyncSubcommand("inspect",(args)->{ registerSyncSubcommand("inspect",(args)->{
if (args.length < 1) return false; if (args.length < 1) return false;
var result = Peripheral.instance.inspect(args[0]); var result = Peripheral.inspect(args[0]);
if (result == null){ if (result == null){
handle.writeLine("No peripheral found on side "+args[0]); handle.writeLine("No peripheral found on side "+args[0]);
@@ -29,8 +29,8 @@ class Perf extends CLIAppBase {
},"<side>"); },"<side>");
registerSyncSubcommand("list",(args)->{ registerSyncSubcommand("list",(args)->{
for (addr in Peripheral.instance.getAllAddresses()){ for (addr in Peripheral.getAllAddresses()){
handle.writeLine('$addr => ${Peripheral.instance.getTypes(addr).join(", ")}'); handle.writeLine('$addr => ${Peripheral.getTypes(addr).join(", ")}');
} }
return true; return true;
}); });

View File

@@ -8,17 +8,17 @@ using tink.CoreApi;
class Redstone extends CLIAppBase{ class Redstone extends CLIAppBase{
public function new() { public function new() {
registerSyncSubcommand("on", (args)-> { registerSyncSubcommand("on", (args)-> {
Peripheral.instance.getRedstone(args[0]).setOutput(true); Peripheral.getRedstone(args[0]).setOutput(true);
return true; return true;
},"<side>"); },"<side>");
registerSyncSubcommand("off", (args)-> { registerSyncSubcommand("off", (args)-> {
Peripheral.instance.getRedstone(args[0]).setOutput(false); Peripheral.getRedstone(args[0]).setOutput(false);
return true; return true;
},"<side>"); },"<side>");
registerSyncSubcommand("get", (args)-> { registerSyncSubcommand("get", (args)-> {
var value = Peripheral.instance.getRedstone(args[0]).getAnalogInput(); var value = Peripheral.getRedstone(args[0]).getAnalogInput();
handle.write("Analog input: " + value); handle.write("Analog input: " + value);
return true; return true;
},"<side>"); },"<side>");

View File

@@ -14,7 +14,7 @@ class Service extends CLIAppBase {
var name = args[0]; var name = args[0];
var result = ServiceManager.instance.start(name); var result = ServiceManager.start(name);
return handleResult(result); return handleResult(result);
},"<name>"); },"<name>");
@@ -25,7 +25,7 @@ class Service extends CLIAppBase {
var name = args[0]; var name = args[0];
var result = ServiceManager.instance.stop(name); var result = ServiceManager.stop(name);
return handleResult(result); return handleResult(result);
},"<name>"); },"<name>");
@@ -38,7 +38,7 @@ class Service extends CLIAppBase {
var binName = args[1]; var binName = args[1];
var rest = args.slice(2); var rest = args.slice(2);
var result = ServiceManager.instance.register(name, binName, rest); var result = ServiceManager.register(name, binName, rest);
return handleResult(result); return handleResult(result);
},"<name> <binary> [args...]"); },"<name> <binary> [args...]");
@@ -49,13 +49,13 @@ class Service extends CLIAppBase {
var name = args[0]; var name = args[0];
var result = ServiceManager.instance.unregister(name); var result = ServiceManager.unregister(name);
return handleResult(result); return handleResult(result);
},"<name>"); },"<name>");
registerSyncSubcommand("list", (args) ->{ registerSyncSubcommand("list", (args) ->{
var list = ServiceManager.instance.listRunning(); var list = ServiceManager.listRunning();
for (name in list) { for (name in list) {
this.handle.writeLine(name); this.handle.writeLine(name);
@@ -69,7 +69,7 @@ class Service extends CLIAppBase {
return false; return false;
} }
ServiceManager.instance.enable(args[0]); ServiceManager.enable(args[0]);
return true; return true;
},"<name>"); },"<name>");
} }

View File

@@ -200,7 +200,7 @@ class Terminal implements Process {
} }
private function getProgByName(name:String):Process { private function getProgByName(name:String):Process {
var bin = BinStore.instance.getBinByAlias(name); var bin = BinStore.getBinByAlias(name);
if (bin == null) { if (bin == null) {
return null; return null;
} }

View File

@@ -25,7 +25,7 @@ class Res extends CLIAppBase {
},"<url>"); },"<url>");
registerAsyncSubcommand("register",(args)->{ registerAsyncSubcommand("register",(args)->{
var srv: Null<ResManager> = ServiceManager.instance.get("resmgr"); var srv: Null<ResManager> = ServiceManager.get("resmgr");
var addr = args[0]; var addr = args[0];
var name = args[1]; var name = args[1];
@@ -35,7 +35,7 @@ class Res extends CLIAppBase {
return false; return false;
} }
var perf: kernel.peripherals.Redstone = Peripheral.instance.getRedstone(addr); var perf: kernel.peripherals.Redstone = Peripheral.getRedstone(addr);
if (perf == null) { if (perf == null) {
handle.writeLine("Error: peripheral not found"); handle.writeLine("Error: peripheral not found");

View File

@@ -21,7 +21,7 @@ class ResManager implements Process {
public function run(handle:ProcessHandle) { public function run(handle:ProcessHandle) {
this.handle = handle; this.handle = handle;
Net.instance.registerProto("res",handlePackage); Net.registerProto("res",handlePackage);
load(); load();
} }
@@ -53,7 +53,7 @@ class ResManager implements Process {
} }
private function registerName(id: String){ private function registerName(id: String){
return RessourceNames.register(id, Net.instance.networkID); return RessourceNames.register(id, Net.networkID);
} }
private function persist(){ private function persist(){
@@ -73,7 +73,7 @@ class ResManager implements Process {
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){ for (export in savedExports){
var perph = Peripheral.instance.getFromType(export.addr,export.type); var perph = Peripheral.getFromType(export.addr,export.type);
if (perph == null){ if (perph == null){
handle.writeLine('Could not load export: ${export.name} on ${export.addr}'); handle.writeLine('Could not load export: ${export.name} on ${export.addr}');

View File

@@ -35,14 +35,14 @@ class PFClient implements Process {
} }
private function render() { private function render() {
var acc = kernel.gps.GPS.instance.getAccuracy(); var acc = kernel.gps.GPS.getAccuracy();
var pos: Pos3 = kernel.gps.GPS.instance.getPosition() ?? {x: 0, y: 0, z: 0}; var pos: Pos3 = kernel.gps.GPS.getPosition() ?? {x: 0, y: 0, z: 0};
var childre: Array<UIElement> = [ var childre: Array<UIElement> = [
new TextElement('Acc: ${acc}'), new TextElement('Acc: ${acc}'),
new TextElement('Pos: X:${pos.x} Y:${pos.y} Z:${pos.z}'), new TextElement('Pos: X:${pos.x} Y:${pos.y} Z:${pos.z}'),
new TextElement('UPDATE', { style: {bgColor: Gray}, uiEvents: {onClick: () -> { new TextElement('UPDATE', { style: {bgColor: Gray}, uiEvents: {onClick: () -> {
kernel.gps.GPS.instance.locate().handle((pos) ->{ kernel.gps.GPS.locate().handle((pos) ->{
this.requestRender(); this.requestRender();
}); });
}}}), }}}),

View File

@@ -25,7 +25,7 @@ class SiteRessourceController implements Process {
load(); load();
// Register proto // Register proto
kernel.net.Net.instance.registerProto(SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO, this.handleMsg); kernel.net.Net.registerProto(SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO, this.handleMsg);
} }
private function handleMsg(pkg:GenericPackage) { private function handleMsg(pkg:GenericPackage) {

View File

@@ -24,42 +24,36 @@ class Init {
public static function initKernel() { public static function initKernel() {
// Init singeltons here because haxe is confused about the order to create them. // Init singeltons here because haxe is confused about the order to create them.
Log.instance = new Log(); Log.init();
KernelEvents.instance = new KernelEvents(); KernelEvents.init();
Peripheral.instance = new Peripheral();
WindowManager.instance = new WindowManager(); WindowManager.init();
MainTerm.instance = new MainTerm(); MainTerm.instance = new MainTerm();
BinStore.instance = new BinStore();
if (Turtle.isTurtle()){ if (Turtle.isTurtle()){
Turtle.instance = new Turtle(); Turtle.instance = new Turtle();
} }
Routing.instance = new Routing(); Routing.init();
Net.instance = new Net(); Net.init();
GPS.instance = new GPS(); GPS.init();
INS.instance = new INS();
// Register default terminate handler // Register default terminate handler
KernelEvents.instance.onTerminate.handle(_->{ KernelEvents.onTerminate.handle(_->{
KernelEvents.instance.shutdown(); KernelEvents.shutdown();
}); });
Debug.printBuildInfo(); Debug.printBuildInfo();
Routing.instance.init();
if (!FS.exists("/var/ns")) { if (!FS.exists("/var/ns")) {
FS.makeDir("/var/ns"); FS.makeDir("/var/ns");
} }
Init.mainEvent = MainLoop.add(()->{ Init.mainEvent = MainLoop.add(()->{
KernelEvents.instance.startEventLoop(); KernelEvents.startEventLoop();
}); });
ServiceManager.instance = new ServiceManager(); ServiceManager.init();
} }
} }

View File

@@ -18,124 +18,122 @@ class KernelEvents {
/** /**
Depends on: (Nothing) Depends on: (Nothing)
**/ **/
public static var instance:KernelEvents; public static var onAlarm(default, null):Signal<Int>;
public static var onChar(default, null):Signal<String>;
public final onAlarm:Signal<Int>; public static var onDisk(default, null):Signal<String>;
public final onChar:Signal<String>; public static var onDiskEject(default, null):Signal<String>;
public final onDisk:Signal<String>; public static var onHttpCheck(default, null):Signal<{url:String, success:Bool, failReason:Any}>;
public final onDiskEject:Signal<String>; public static var onHttpFailure(default, null):Signal<{url:String, failReason:String, handle:HTTPResponse}>;
public final onHttpCheck:Signal<{url:String, success:Bool, failReason:Any}>; public static var onHttpSuccess(default, null):Signal<{url:String, handle:HTTPResponse}>;
public final onHttpFailure:Signal<{url:String, failReason:String, handle:HTTPResponse}>; public static var onKey(default, null):Signal<{keyCode:Int, isHeld:Bool}>;
public final onHttpSuccess:Signal<{url:String, handle:HTTPResponse}>; public static var onKeyUp(default, null):Signal<Int>;
public final onKey:Signal<{keyCode:Int, isHeld:Bool}>; public static var onModemMessage(default, null):Signal<{
public final onKeyUp:Signal<Int>;
public final onModemMessage:Signal<{
addr:String, addr:String,
channel:Int, channel:Int,
replyChannel:Int, replyChannel:Int,
message:Dynamic, message:Dynamic,
distance:Null<Float> distance:Null<Float>
}>; }>;
public final onMonitorResize:Signal<String>; public static var onMonitorResize(default, null):Signal<String>;
public final onMonitorTouch:Signal<{addr:String, pos:Pos}>; public static var onMonitorTouch(default, null):Signal<{addr:String, pos:Pos}>;
public final onMouseClick:Signal<{button:ButtonType, pos:Pos}>; public static var onMouseClick(default, null):Signal<{button:ButtonType, pos:Pos}>;
public final onMouseDrag:Signal<{button:ButtonType, pos:Pos}>; public static var onMouseDrag(default, null):Signal<{button:ButtonType, pos:Pos}>;
public final onMouseScroll:Signal<{dir:Int, pos:Pos}>; public static var onMouseScroll(default, null):Signal<{dir:Int, pos:Pos}>;
public final onMouseUp:Signal<{button:ButtonType, pos:Pos}>; public static var onMouseUp(default, null):Signal<{button:ButtonType, pos:Pos}>;
public final onPaste:Signal<String>; public static var onPaste(default, null):Signal<String>;
public final onPeripheral:Signal<String>; public static var onPeripheral(default, null):Signal<String>;
public final onPeripheralDetach:Signal<String>; public static var onPeripheralDetach(default, null):Signal<String>;
public final onRedstone:Signal<Noise>; public static var onRedstone(default, null):Signal<Noise>;
public final onSpeakerAudioEmpty:Signal<String>; public static var onSpeakerAudioEmpty(default, null):Signal<String>;
public final onTaskComplete:Signal<{id:Int, success:Bool, failedReason:String}>; public static var onTaskComplete(default, null):Signal<{id:Int, success:Bool, failedReason:String}>;
public final onTermResize:Signal<Noise>; public static var onTermResize(default, null):Signal<Noise>;
public final onTerminate:Signal<Noise>; public static var onTerminate(default, null):Signal<Noise>;
public final onTimer:Signal<Int>; public static var onTimer(default, null):Signal<Int>;
public final onTurtleInventory:Signal<Noise>; public static var onTurtleInventory(default, null):Signal<Noise>;
public final onWebsocketClose:Signal<String>; public static var onWebsocketClose(default, null):Signal<String>;
public final onWebsocketFailure:Signal<{url:String, failReason:String}>; public static var onWebsocketFailure(default, null):Signal<{url:String, failReason:String}>;
public final onWebsocketMessage:Signal<{url:String, message:String, isBinary:Bool}>; public static var onWebsocketMessage(default, null):Signal<{url:String, message:String, isBinary:Bool}>;
public final onWebsocketSuccess:Signal<{url:String, handle:Any}>; public static var onWebsocketSuccess(default, null):Signal<{url:String, handle:Any}>;
private final onAlarmTrigger:SignalTrigger<Int> = Signal.trigger(); private static final onAlarmTrigger:SignalTrigger<Int> = Signal.trigger();
private final onCharTrigger:SignalTrigger<String> = Signal.trigger(); private static final onCharTrigger:SignalTrigger<String> = Signal.trigger();
private final onDiskTrigger:SignalTrigger<String> = Signal.trigger(); private static final onDiskTrigger:SignalTrigger<String> = Signal.trigger();
private final onDiskEjectTrigger:SignalTrigger<String> = Signal.trigger(); private static final onDiskEjectTrigger:SignalTrigger<String> = Signal.trigger();
private final onHttpCheckTrigger:SignalTrigger<{url:String, success:Bool, failReason:Any}> = Signal.trigger(); private static final onHttpCheckTrigger:SignalTrigger<{url:String, success:Bool, failReason:Any}> = Signal.trigger();
private final onHttpFailureTrigger:SignalTrigger<{url:String, failReason:String, handle:HTTPResponse}> = Signal.trigger(); private static final onHttpFailureTrigger:SignalTrigger<{url:String, failReason:String, handle:HTTPResponse}> = Signal.trigger();
private final onHttpSuccessTrigger:SignalTrigger<{url:String, handle:HTTPResponse}> = Signal.trigger(); private static final onHttpSuccessTrigger:SignalTrigger<{url:String, handle:HTTPResponse}> = Signal.trigger();
private final onKeyTrigger:SignalTrigger<{keyCode:Int, isHeld:Bool}> = Signal.trigger(); private static final onKeyTrigger:SignalTrigger<{keyCode:Int, isHeld:Bool}> = Signal.trigger();
private final onKeyUpTrigger:SignalTrigger<Int> = Signal.trigger(); private static final onKeyUpTrigger:SignalTrigger<Int> = Signal.trigger();
private final onModemMessageTrigger:SignalTrigger<{ private static final onModemMessageTrigger:SignalTrigger<{
addr:String, addr:String,
channel:Int, channel:Int,
replyChannel:Int, replyChannel:Int,
message:Dynamic, message:Dynamic,
distance:Null<Float> distance:Null<Float>
}> = Signal.trigger(); }> = Signal.trigger();
private final onMonitorResizeTrigger:SignalTrigger<String> = Signal.trigger(); private static final onMonitorResizeTrigger:SignalTrigger<String> = Signal.trigger();
private final onMonitorTouchTrigger:SignalTrigger<{addr:String, pos:Pos}> = Signal.trigger(); private static final onMonitorTouchTrigger:SignalTrigger<{addr:String, pos:Pos}> = Signal.trigger();
private final onMouseClickTrigger:SignalTrigger<{button:ButtonType, pos:Pos}> = Signal.trigger(); private static final onMouseClickTrigger:SignalTrigger<{button:ButtonType, pos:Pos}> = Signal.trigger();
private final onMouseDragTrigger:SignalTrigger<{button:ButtonType, pos:Pos}> = Signal.trigger(); private static final onMouseDragTrigger:SignalTrigger<{button:ButtonType, pos:Pos}> = Signal.trigger();
private final onMouseScrollTrigger:SignalTrigger<{dir:Int, pos:Pos}> = Signal.trigger(); private static final onMouseScrollTrigger:SignalTrigger<{dir:Int, pos:Pos}> = Signal.trigger();
private final onMouseUpTrigger:SignalTrigger<{button:ButtonType, pos:Pos}> = Signal.trigger(); private static final onMouseUpTrigger:SignalTrigger<{button:ButtonType, pos:Pos}> = Signal.trigger();
private final onPasteTrigger:SignalTrigger<String> = Signal.trigger(); private static final onPasteTrigger:SignalTrigger<String> = Signal.trigger();
private final onPeripheralTrigger:SignalTrigger<String> = Signal.trigger(); private static final onPeripheralTrigger:SignalTrigger<String> = Signal.trigger();
private final onPeripheralDetachTrigger:SignalTrigger<String> = Signal.trigger(); private static final onPeripheralDetachTrigger:SignalTrigger<String> = Signal.trigger();
private final onRednetMessageTrigger:SignalTrigger<{sender:Int, message:Any, protocol:Any}> = Signal.trigger(); private static final onRednetMessageTrigger:SignalTrigger<{sender:Int, message:Any, protocol:Any}> = Signal.trigger();
private final onRedstoneTrigger:SignalTrigger<Noise> = Signal.trigger(); private static final onRedstoneTrigger:SignalTrigger<Noise> = Signal.trigger();
private final onSpeakerAudioEmptyTrigger:SignalTrigger<String> = Signal.trigger(); private static final onSpeakerAudioEmptyTrigger:SignalTrigger<String> = Signal.trigger();
private final onTaskCompleteTrigger:SignalTrigger<{id:Int, success:Bool, failedReason:String}> = Signal.trigger(); private static final onTaskCompleteTrigger:SignalTrigger<{id:Int, success:Bool, failedReason:String}> = Signal.trigger();
private final onTermResizeTrigger:SignalTrigger<Noise> = Signal.trigger(); private static final onTermResizeTrigger:SignalTrigger<Noise> = Signal.trigger();
private final onTerminateTrigger:SignalTrigger<Noise> = Signal.trigger(); private static final onTerminateTrigger:SignalTrigger<Noise> = Signal.trigger();
private final onTimerTrigger:SignalTrigger<Int> = Signal.trigger(); private static final onTimerTrigger:SignalTrigger<Int> = Signal.trigger();
private final onTurtleInventoryTrigger:SignalTrigger<Noise> = Signal.trigger(); private static final onTurtleInventoryTrigger:SignalTrigger<Noise> = Signal.trigger();
private final onWebsocketCloseTrigger:SignalTrigger<String> = Signal.trigger(); private static final onWebsocketCloseTrigger:SignalTrigger<String> = Signal.trigger();
private final onWebsocketFailureTrigger:SignalTrigger<{url:String, failReason:String}> = Signal.trigger(); private static final onWebsocketFailureTrigger:SignalTrigger<{url:String, failReason:String}> = Signal.trigger();
private final onWebsocketMessageTrigger:SignalTrigger<{url:String, message:String, isBinary:Bool}> = Signal.trigger(); private static final onWebsocketMessageTrigger:SignalTrigger<{url:String, message:String, isBinary:Bool}> = Signal.trigger();
private final onWebsocketSuccessTrigger:SignalTrigger<{url:String, handle:Any}> = Signal.trigger(); private static final onWebsocketSuccessTrigger:SignalTrigger<{url:String, handle:Any}> = Signal.trigger();
private var stopLoop:Bool = false; private static var stopLoop:Bool = false;
@:allow(kernel.Init) @:allow(kernel.Init)
private function new() { private static function init() {
this.onAlarm = onAlarmTrigger.asSignal(); onAlarm = onAlarmTrigger.asSignal();
this.onChar = onCharTrigger.asSignal(); onChar = onCharTrigger.asSignal();
this.onDisk = onDiskTrigger.asSignal(); onDisk = onDiskTrigger.asSignal();
this.onDiskEject = onDiskEjectTrigger.asSignal(); onDiskEject = onDiskEjectTrigger.asSignal();
this.onHttpCheck = onHttpCheckTrigger.asSignal(); onHttpCheck = onHttpCheckTrigger.asSignal();
this.onHttpFailure = onHttpFailureTrigger.asSignal(); onHttpFailure = onHttpFailureTrigger.asSignal();
this.onHttpSuccess = onHttpSuccessTrigger.asSignal(); onHttpSuccess = onHttpSuccessTrigger.asSignal();
this.onKey = onKeyTrigger.asSignal(); onKey = onKeyTrigger.asSignal();
this.onKeyUp = onKeyUpTrigger.asSignal(); onKeyUp = onKeyUpTrigger.asSignal();
this.onModemMessage = onModemMessageTrigger.asSignal(); onModemMessage = onModemMessageTrigger.asSignal();
this.onMonitorResize = onMonitorResizeTrigger.asSignal(); onMonitorResize = onMonitorResizeTrigger.asSignal();
this.onMonitorTouch = onMonitorTouchTrigger.asSignal(); onMonitorTouch = onMonitorTouchTrigger.asSignal();
this.onMouseClick = onMouseClickTrigger.asSignal(); onMouseClick = onMouseClickTrigger.asSignal();
this.onMouseDrag = onMouseDragTrigger.asSignal(); onMouseDrag = onMouseDragTrigger.asSignal();
this.onMouseScroll = onMouseScrollTrigger.asSignal(); onMouseScroll = onMouseScrollTrigger.asSignal();
this.onMouseUp = onMouseUpTrigger.asSignal(); onMouseUp = onMouseUpTrigger.asSignal();
this.onPaste = onPasteTrigger.asSignal(); onPaste = onPasteTrigger.asSignal();
this.onPeripheral = onPeripheralTrigger.asSignal(); onPeripheral = onPeripheralTrigger.asSignal();
this.onPeripheralDetach = onPeripheralDetachTrigger.asSignal(); onPeripheralDetach = onPeripheralDetachTrigger.asSignal();
this.onRedstone = onRedstoneTrigger.asSignal(); onRedstone = onRedstoneTrigger.asSignal();
this.onSpeakerAudioEmpty = onSpeakerAudioEmptyTrigger.asSignal(); onSpeakerAudioEmpty = onSpeakerAudioEmptyTrigger.asSignal();
this.onTaskComplete = onTaskCompleteTrigger.asSignal(); onTaskComplete = onTaskCompleteTrigger.asSignal();
this.onTermResize = onTermResizeTrigger.asSignal(); onTermResize = onTermResizeTrigger.asSignal();
this.onTerminate = onTerminateTrigger.asSignal(); onTerminate = onTerminateTrigger.asSignal();
this.onTimer = onTimerTrigger.asSignal(); onTimer = onTimerTrigger.asSignal();
this.onTurtleInventory = onTurtleInventoryTrigger.asSignal(); onTurtleInventory = onTurtleInventoryTrigger.asSignal();
this.onWebsocketClose = onWebsocketCloseTrigger.asSignal(); onWebsocketClose = onWebsocketCloseTrigger.asSignal();
this.onWebsocketFailure = onWebsocketFailureTrigger.asSignal(); onWebsocketFailure = onWebsocketFailureTrigger.asSignal();
this.onWebsocketMessage = onWebsocketMessageTrigger.asSignal(); onWebsocketMessage = onWebsocketMessageTrigger.asSignal();
this.onWebsocketSuccess = onWebsocketSuccessTrigger.asSignal(); onWebsocketSuccess = onWebsocketSuccessTrigger.asSignal();
} }
/** /**
Start pulling events. Blocking. Start pulling events. Blocking.
**/ **/
@:allow(kernel.Init) @:allow(kernel.Init)
private function startEventLoop() { private static function startEventLoop() {
while (!stopLoop) { while (!stopLoop) {
var event:Table<Int, Dynamic> = pullEvents(); var event:Table<Int, Dynamic> = pullEvents();
@@ -148,45 +146,45 @@ class KernelEvents {
} }
} }
public function shutdown() { public static function shutdown() {
// clearing screens // clearing screens
for (screen in Peripheral.instance.getAllScreens()) { for (screen in Peripheral.getAllScreens()) {
screen.reset(); screen.reset();
} }
Log.info('Shutting down event loop'); Log.info('Shutting down event loop');
this.stopLoop = true; stopLoop = true;
MainTerm.instance.reset(); MainTerm.instance.reset();
Init.mainEvent.stop(); Init.mainEvent.stop();
} }
private function pullEvents():Table<Int, Dynamic> { private static function pullEvents():Table<Int, Dynamic> {
return cast TableTools.pack(Coroutine.yield(null)); return cast TableTools.pack(Coroutine.yield(null));
} }
private function fireSignal(eventName: String,event:Table<Int, Dynamic> ) { private static function fireSignal(eventName: String,event:Table<Int, Dynamic> ) {
switch eventName { switch eventName {
case "alarm": case "alarm":
this.onAlarmTrigger.trigger(event[2]); onAlarmTrigger.trigger(event[2]);
case "char": case "char":
this.onCharTrigger.trigger(event[2]); onCharTrigger.trigger(event[2]);
case "disk": case "disk":
this.onDiskTrigger.trigger(event[2]); onDiskTrigger.trigger(event[2]);
case "disk_eject": case "disk_eject":
this.onDiskEjectTrigger.trigger(event[2]); onDiskEjectTrigger.trigger(event[2]);
case "http_check": case "http_check":
this.onHttpCheckTrigger.trigger({url: event[2], success: event[3], failReason: event[4]}); onHttpCheckTrigger.trigger({url: event[2], success: event[3], failReason: event[4]});
case "http_failure": case "http_failure":
this.onHttpFailureTrigger.trigger({url: event[2], failReason: event[3], handle: event[4]}); onHttpFailureTrigger.trigger({url: event[2], failReason: event[3], handle: event[4]});
case "http_success": case "http_success":
this.onHttpSuccessTrigger.trigger({url: event[2], handle: event[3]}); onHttpSuccessTrigger.trigger({url: event[2], handle: event[3]});
case "key": case "key":
this.onKeyTrigger.trigger({keyCode: event[2], isHeld: event[3]}); onKeyTrigger.trigger({keyCode: event[2], isHeld: event[3]});
case "key_up": case "key_up":
this.onKeyUpTrigger.trigger(event[2]); onKeyUpTrigger.trigger(event[2]);
case "modem_message": case "modem_message":
this.onModemMessageTrigger.trigger({ onModemMessageTrigger.trigger({
addr: event[2], addr: event[2],
channel: event[3], channel: event[3],
replyChannel: event[4], replyChannel: event[4],
@@ -194,45 +192,45 @@ class KernelEvents {
distance: event[6] distance: event[6]
}); });
case "monitor_resize": case "monitor_resize":
this.onMonitorResizeTrigger.trigger(event[2]); onMonitorResizeTrigger.trigger(event[2]);
case "monitor_touch": case "monitor_touch":
this.onMonitorTouchTrigger.trigger({addr: event[2], pos: {x: (event[3] : Int) - 1, y: (event[4] : Int) - 1}}); onMonitorTouchTrigger.trigger({addr: event[2], pos: {x: (event[3] : Int) - 1, y: (event[4] : Int) - 1}});
case "mouse_click": case "mouse_click":
this.onMouseClickTrigger.trigger({button: ccButtonToEnum(event[2]), pos: {x: (event[3] : Int) - 1, y: (event[4] : Int) - 1}}); onMouseClickTrigger.trigger({button: ccButtonToEnum(event[2]), pos: {x: (event[3] : Int) - 1, y: (event[4] : Int) - 1}});
case "mouse_drag": case "mouse_drag":
this.onMouseDragTrigger.trigger({button: ccButtonToEnum(event[2]), pos: {x: (event[3] : Int) - 1, y: (event[4] : Int) - 1}}); onMouseDragTrigger.trigger({button: ccButtonToEnum(event[2]), pos: {x: (event[3] : Int) - 1, y: (event[4] : Int) - 1}});
case "mouse_scroll": case "mouse_scroll":
this.onMouseScrollTrigger.trigger({dir: event[2], pos: {x: (event[3] : Int) - 1, y: (event[4] : Int) - 1}}); onMouseScrollTrigger.trigger({dir: event[2], pos: {x: (event[3] : Int) - 1, y: (event[4] : Int) - 1}});
case "mouse_up": case "mouse_up":
this.onMouseUpTrigger.trigger({button: ccButtonToEnum(event[2]), pos: {x: (event[3] : Int) - 1, y: (event[4] : Int) - 1}}); onMouseUpTrigger.trigger({button: ccButtonToEnum(event[2]), pos: {x: (event[3] : Int) - 1, y: (event[4] : Int) - 1}});
case "paste": case "paste":
this.onPasteTrigger.trigger(event[2]); onPasteTrigger.trigger(event[2]);
case "peripheral": case "peripheral":
this.onPeripheralTrigger.trigger(event[2]); onPeripheralTrigger.trigger(event[2]);
case "peripheral_detach": case "peripheral_detach":
this.onPeripheralDetachTrigger.trigger(event[2]); onPeripheralDetachTrigger.trigger(event[2]);
case "redstone": case "redstone":
this.onRedstoneTrigger.trigger(null); onRedstoneTrigger.trigger(null);
case "speaker_audio_empty": case "speaker_audio_empty":
this.onSpeakerAudioEmptyTrigger.trigger(event[2]); onSpeakerAudioEmptyTrigger.trigger(event[2]);
case "task_complete": case "task_complete":
this.onTaskCompleteTrigger.trigger({id: event[2], success: event[3], failedReason: event[4]}); onTaskCompleteTrigger.trigger({id: event[2], success: event[3], failedReason: event[4]});
case "term_resize": case "term_resize":
this.onTermResizeTrigger.trigger(null); onTermResizeTrigger.trigger(null);
case "terminate": case "terminate":
this.onTerminateTrigger.trigger(null); onTerminateTrigger.trigger(null);
case "timer": case "timer":
this.onTimerTrigger.trigger(event[2]); onTimerTrigger.trigger(event[2]);
case "turtle_inventory": case "turtle_inventory":
this.onTurtleInventoryTrigger.trigger(null); onTurtleInventoryTrigger.trigger(null);
case "websocket_closed": case "websocket_closed":
this.onWebsocketCloseTrigger.trigger(event[2]); onWebsocketCloseTrigger.trigger(event[2]);
case "websocket_failure": case "websocket_failure":
this.onWebsocketFailureTrigger.trigger({url: event[2], failReason: event[3]}); onWebsocketFailureTrigger.trigger({url: event[2], failReason: event[3]});
case "websocket_message": case "websocket_message":
this.onWebsocketMessageTrigger.trigger({url: event[2], message: event[3], isBinary: event[4]}); onWebsocketMessageTrigger.trigger({url: event[2], message: event[3], isBinary: event[4]});
case "websocket_success": case "websocket_success":
this.onWebsocketSuccessTrigger.trigger({url: event[2], handle: event[3]}); onWebsocketSuccessTrigger.trigger({url: event[2], handle: event[3]});
case "endofloop": case "endofloop":
EndOfLoop.run(); EndOfLoop.run();
default: default:
@@ -254,7 +252,7 @@ class KernelEvents {
} }
@:allow(lib.Debug) @:allow(lib.Debug)
private function printListenerCount() { private static function printListenerCount() {
if (onAlarmTrigger.getLength() > 0) Log.debug("onAlarm: " + onAlarmTrigger.getLength()); if (onAlarmTrigger.getLength() > 0) Log.debug("onAlarm: " + onAlarmTrigger.getLength());
if (onCharTrigger.getLength() > 0) Log.debug("onChar: " + onCharTrigger.getLength()); if (onCharTrigger.getLength() > 0) Log.debug("onChar: " + onCharTrigger.getLength());
if (onDiskTrigger.getLength() > 0) Log.debug("onDisk: " + onDiskTrigger.getLength()); if (onDiskTrigger.getLength() > 0) Log.debug("onDisk: " + onDiskTrigger.getLength());

View File

@@ -26,7 +26,7 @@ class MainTerm implements TermWriteable {
this.onResizeTrigger = Signal.trigger(); this.onResizeTrigger = Signal.trigger();
this.onResize = this.onResizeTrigger.asSignal(); this.onResize = this.onResizeTrigger.asSignal();
KernelEvents.instance.onTermResize.handle(_ -> { KernelEvents.onTermResize.handle(_ -> {
onResizeTrigger.trigger(getSize()); onResizeTrigger.trigger(getSize());
}); });
} }

View File

@@ -19,7 +19,7 @@ class Timer {
timerID = OS.startTimer(timeout); timerID = OS.startTimer(timeout);
this.callback = callback; this.callback = callback;
timerLink = KernelEvents.instance.onTimer.handle(timerID -> { timerLink = KernelEvents.onTimer.handle(timerID -> {
if (this.timerID == timerID) { if (this.timerID == timerID) {
callback.invoke(null); callback.invoke(null);
timerLink.cancel(); timerLink.cancel();

View File

@@ -22,9 +22,7 @@ import bin.Disk;
import haxe.ds.ReadOnlyArray; import haxe.ds.ReadOnlyArray;
class BinStore { class BinStore {
public static var instance: BinStore; private static final store:ReadOnlyArray<Bin> = [
private final store:ReadOnlyArray<Bin> = [
{c: Disk, name: "Disk", aliases: ["disk"]}, {c: Disk, name: "Disk", aliases: ["disk"]},
{c: GPS, name: "GPS", aliases: ["gps"]}, {c: GPS, name: "GPS", aliases: ["gps"]},
{c: HelloWorld, name: "HelloWorld", aliases: ["hello"]}, {c: HelloWorld, name: "HelloWorld", aliases: ["hello"]},
@@ -46,12 +44,7 @@ class BinStore {
{c: PFClient, name: "PFClient", aliases: ["pfclient"]} {c: PFClient, name: "PFClient", aliases: ["pfclient"]}
]; ];
@:allow(kernel.Init) public static function getBinByName(name:String):Null<Bin> {
private function new() {
}
public function getBinByName(name:String):Null<Bin> {
for (bin in store) { for (bin in store) {
if (bin.name == name) { if (bin.name == name) {
return bin; return bin;
@@ -60,7 +53,7 @@ class BinStore {
return null; return null;
} }
public function getBinByAlias(alias:String):Null<Bin> { public static function getBinByAlias(alias:String):Null<Bin> {
for (bin in store) { for (bin in store) {
for (a in bin.aliases) { for (a in bin.aliases) {
if (a == alias) { if (a == alias) {
@@ -71,7 +64,7 @@ class BinStore {
return null; return null;
} }
public function getNameByAlias(alias: String): String { public static function getNameByAlias(alias: String): String {
var bin = getBinByAlias(alias); var bin = getBinByAlias(alias);
if (bin == null) { if (bin == null) {
return null; return null;

View File

@@ -15,22 +15,20 @@ using tink.CoreApi;
You need at least 3 computers that know their position to determine the position of the computer. You need at least 3 computers that know their position to determine the position of the computer.
**/ **/
class GPS { class GPS {
public static var instance:GPS; private static var shouldRespond = true;
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 var shouldRespond = true; private static var futureResolve: (pos:Null<Pos3>) -> Void = null;
private var shouldDoWholeNumberCheck = true;
private var posAccuracy = 0; // 0 = unkown, 1 = (ins,best guess), 2 = (stored/manual,should be right), 3 = (gps,confirmed)
private var cachedPosition:Pos3;
private var lastPositionResponse: Array<{pos:Pos3,dist:Float}> = [];
private var futureResolve: (pos:Null<Pos3>) -> Void = null;
@:allow(kernel.Init) @:allow(kernel.Init)
private function new() { private static function init() {
this.loadCachedPosition(); loadCachedPosition();
} }
public function setManualPosition(pos:Pos3) { public static function setManualPosition(pos:Pos3) {
var kvstore = new KVStore("gps"); var kvstore = new KVStore("gps");
kvstore.set("mpos",pos); kvstore.set("mpos",pos);
kvstore.save(); kvstore.save();
@@ -42,39 +40,39 @@ class GPS {
} }
@:allow(kernel.gps.INS) @:allow(kernel.gps.INS)
private function setINSPosition(pos:Pos3) { private static function setINSPosition(pos:Pos3) {
cachedPosition = pos; cachedPosition = pos;
posAccuracy = 1; posAccuracy = 1;
} }
public function getPosition():Null<Pos3> { public static function getPosition():Null<Pos3> {
return cachedPosition; return cachedPosition;
} }
public function getAccuracy():Int { public static function getAccuracy():Int {
return posAccuracy; return posAccuracy;
} }
public function invalidatePosition() { public static function invalidatePosition() {
cachedPosition = null; cachedPosition = null;
posAccuracy = 0; posAccuracy = 0;
} }
public function locate():Future<Null<Pos3>> { public static function locate():Future<Null<Pos3>> {
// TODO: implenet a timeout // TODO: implenet a timeout
// TODO: dont send a request twice if the last one is still pending or we moved // 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)->{
this.futureResolve = resolve; futureResolve = resolve;
sendPositionRequest(); sendPositionRequest();
return null; return null;
}); });
} }
private function resolveFuture(pos:Null<Pos3>) { private static function resolveFuture(pos:Null<Pos3>) {
this.futureResolve(pos); futureResolve(pos);
} }
private function persistCachedPositon() { private static function persistCachedPositon() {
if (cachedPosition == null) return; if (cachedPosition == null) return;
var kvstore = new KVStore("gps"); var kvstore = new KVStore("gps");
@@ -82,7 +80,7 @@ class GPS {
kvstore.save(); kvstore.save();
} }
private function loadCachedPosition() { private static function loadCachedPosition() {
var kvstore = new KVStore("gps"); var kvstore = new KVStore("gps");
kvstore.load(); kvstore.load();
@@ -119,20 +117,20 @@ class GPS {
} }
private function sendPositionRequest() { private static function sendPositionRequest() {
Net.instance.brodcastGPSRequest(); Net.brodcastGPSRequest();
} }
@:allow(kernel.net.Net) @:allow(kernel.net.Net)
private function handlePackage(pack:Package<Noise>, dist: Float,iface: INetworkInterface) { private static function handlePackage(pack:Package<Noise>, dist: Float,iface: INetworkInterface) {
switch (pack.type) { switch (pack.type) {
case GPSRequest: case GPSRequest:
if (!shouldRespond) return; if (!shouldRespond) return;
if (posAccuracy < 2) return; if (posAccuracy < 2) return;
if (cachedPosition == null) return; if (cachedPosition == null) return;
var response = new Package(Net.instance.networkID,pack.fromID, pack.msgID, GPSResponse(cachedPosition),null,0); var response = new Package(Net.networkID,pack.fromID, pack.msgID, GPSResponse(cachedPosition),null,0);
iface.send(pack.fromID,Net.instance.networkID,response); iface.send(pack.fromID,Net.networkID,response);
case GPSResponse(pos): 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
@@ -159,7 +157,7 @@ class GPS {
} }
} }
private function calculatePosition():Null<Pos3> { 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 // do a simple trilateration with the last 3 responses for now
@@ -210,7 +208,7 @@ class GPS {
/** /**
Determines the position(s) of a point given 3 other points and the distance to each of them. Determines the position(s) of a point given 3 other points and the distance to each of them.
**/ **/
private 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 a2b = p2 - p1;
var a2c = p3 - p1; var a2c = p3 - p1;

View File

@@ -7,46 +7,39 @@ import lib.Pos3;
using tink.CoreApi; using tink.CoreApi;
class INS { class INS {
public static var instance:INS; private static var heading: Null<Pos3> = null;
private static var alingment: Int = 1; // 0 = degraded, 1 = not aligned, 2 = aligned
private var heading: Null<Pos3> = null;
private var alingment: Int = 1; // 0 = degraded, 1 = not aligned, 2 = aligned
@:allow(kernel.Init)
private function new() {
}
@:allow(kernel.turtle.Turtle) @:allow(kernel.turtle.Turtle)
private function moveForward() { private static function moveForward() {
if (heading == null) { if (heading == null) {
this.alingment = 0; alingment = 0;
return; return;
} }
move(heading); move(heading);
} }
@:allow(kernel.turtle.Turtle) @:allow(kernel.turtle.Turtle)
private function moveBackward() { private static function moveBackward() {
if (heading == null) { if (heading == null) {
this.alingment = 0; alingment = 0;
return; return;
} }
move(heading.negate()); move(heading.negate());
} }
@:allow(kernel.turtle.Turtle) @:allow(kernel.turtle.Turtle)
private function moveUp() { private static function moveUp() {
move({x: 0, y: 1, z: 0}); move({x: 0, y: 1, z: 0});
} }
@:allow(kernel.turtle.Turtle) @:allow(kernel.turtle.Turtle)
private function moveDown() { private static function moveDown() {
move({x: 0, y: -1, z: 0}); move({x: 0, y: -1, z: 0});
} }
@:allow(kernel.turtle.Turtle) @:allow(kernel.turtle.Turtle)
private function turnLeft() { private static function turnLeft() {
if (heading == null) return; if (heading == null) return;
if (heading.x == 0 && heading.z == -1) { if (heading.x == 0 && heading.z == -1) {
heading = {x: -1, y: 0, z: 0}; heading = {x: -1, y: 0, z: 0};
@@ -60,7 +53,7 @@ class INS {
} }
@:allow(kernel.turtle.Turtle) @:allow(kernel.turtle.Turtle)
private function turnRight() { private static function turnRight() {
if (heading == null) return; if (heading == null) return;
if (heading.x == 0 && heading.z == -1) { if (heading.x == 0 && heading.z == -1) {
heading = {x: 1, y: 0, z: 0}; heading = {x: 1, y: 0, z: 0};
@@ -73,18 +66,18 @@ class INS {
} }
} }
private function move(dir: Null<Pos3>) { private static function move(dir: Null<Pos3>) {
Log.debug('INS move: $dir'); Log.debug('INS move: $dir');
var pos = GPS.instance.getPosition(); var pos = GPS.getPosition();
var newPos = pos + dir; var newPos = pos + dir;
GPS.instance.setINSPosition(newPos); GPS.setINSPosition(newPos);
} }
public function getHeading():Null<Pos3> { public static function getHeading():Null<Pos3> {
return heading; return heading;
} }
public function align(): Promise<Noise> { public static function align(): Promise<Noise> {
Log.info("Aligning INS"); Log.info("Aligning INS");
return new Promise<Noise>((resolve,reject)->{ return new Promise<Noise>((resolve,reject)->{
@@ -94,7 +87,7 @@ class INS {
return null; return null;
} }
GPS.instance.locate().handle((pos1)->{ GPS.locate().handle((pos1)->{
Log.debug('pos1: $pos1'); Log.debug('pos1: $pos1');
if (pos1 == null) { if (pos1 == null) {
Log.warn("GPS not available for 1st position"); Log.warn("GPS not available for 1st position");
@@ -110,7 +103,7 @@ class INS {
return; return;
} }
GPS.instance.locate().handle((pos2)->{ GPS.locate().handle((pos2)->{
Log.debug('pos2: $pos2'); Log.debug('pos2: $pos2');
if (pos2 == null) { if (pos2 == null) {
Log.warn("GPS not available for 2nd position"); Log.warn("GPS not available for 2nd position");
@@ -118,16 +111,16 @@ class INS {
return; return;
} }
var heading = calcHeading(pos1,pos2,moved); var cHeading = calcHeading(pos1,pos2,moved);
if (heading == null) { if (cHeading == null) {
Log.error("Can't calculate heading"); Log.error("Can't calculate heading");
reject(new Error("Can't calculate heading")); reject(new Error("Can't calculate heading"));
return; return;
} }
this.heading = heading; heading = cHeading;
moveBack(moved); moveBack(moved);
GPS.instance.setINSPosition(pos1); GPS.setINSPosition(pos1);
resolve(Noise); resolve(Noise);
}); });
@@ -138,7 +131,7 @@ class INS {
} }
// -1 = not moved, 0 = back, 1 = forward, 2 = left, 3 = right // -1 = not moved, 0 = back, 1 = forward, 2 = left, 3 = right
private function tryMoving():Int { private static function tryMoving():Int {
if (Turtle.instance.back().isSuccess()) { if (Turtle.instance.back().isSuccess()) {
return 0; return 0;
} else if (Turtle.instance.forward().isSuccess()) { } else if (Turtle.instance.forward().isSuccess()) {
@@ -156,7 +149,7 @@ class INS {
} }
} }
private 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) { if (moved == 0) {
return pos1 - pos2; return pos1 - pos2;
} else if (moved == 1) { } else if (moved == 1) {
@@ -170,7 +163,7 @@ class INS {
} }
} }
private function moveBack(moved:Int) { private static function moveBack(moved:Int) {
if (moved == 0) { if (moved == 0) {
Turtle.instance.forward(); Turtle.instance.forward();
// cc.Turtle.forward(); // cc.Turtle.forward();
@@ -190,7 +183,7 @@ class INS {
} }
} }
private function rotatePos3ToRight(pos:Pos3):Pos3 { private static function rotatePos3ToRight(pos:Pos3):Pos3 {
if (pos.x == 0 && pos.z == -1) { if (pos.x == 0 && pos.z == -1) {
return {x: 1, y: 0, z: 0}; return {x: 1, y: 0, z: 0};
} else if (pos.x == -1 && pos.z == 0) { } else if (pos.x == -1 && pos.z == 0) {
@@ -204,7 +197,7 @@ class INS {
} }
} }
private function rotatePos3ToLeft(pos3:Pos3):Pos3 { private static function rotatePos3ToLeft(pos3:Pos3):Pos3 {
return rotatePos3ToRight(rotatePos3ToRight(rotatePos3ToRight(pos3))); return rotatePos3ToRight(rotatePos3ToRight(rotatePos3ToRight(pos3)));
} }

View File

@@ -8,13 +8,13 @@ using tink.CoreApi;
class Http { class Http {
public static function request(url:String,?body:String,?options: String):Future<Outcome<HTTPResponse,HTTPFailure>> { public static function request(url:String,?body:String,?options: String):Future<Outcome<HTTPResponse,HTTPFailure>> {
return new Future<Outcome<HTTPResponse,HTTPFailure>>((resolve) -> { return new Future<Outcome<HTTPResponse,HTTPFailure>>((resolve) -> {
KernelEvents.instance.onHttpFailure.handle((params)->{ KernelEvents.onHttpFailure.handle((params)->{
if (params.url == url){ if (params.url == url){
resolve(Failure(new HTTPFailure(params.failReason,params.handle))); resolve(Failure(new HTTPFailure(params.failReason,params.handle)));
} }
}); });
KernelEvents.instance.onHttpSuccess.handle((params) -> { KernelEvents.onHttpSuccess.handle((params) -> {
if (params.url == url){ if (params.url == url){
resolve(Success(new HTTPResponse(params.handle))); resolve(Success(new HTTPResponse(params.handle)));
} }

View File

@@ -11,42 +11,41 @@ using tink.CoreApi;
Central logging system. Central logging system.
**/ **/
class Log { class Log {
public static var instance:Log;
private static inline final MAX_LINES:Int = 100; private static inline final MAX_LINES:Int = 100;
public final onLog:Signal<LogLine>; public static var onLog(default, null):Signal<LogLine>;
private final onLogTrigger:SignalTrigger<LogLine> = new SignalTrigger(); private static final onLogTrigger:SignalTrigger<LogLine> = new SignalTrigger();
private final logLines:Array<LogLine> = []; private static final logLines:Array<LogLine> = [];
public function new() { @:allow(kernel.Init)
private static function init() {
onLog = onLogTrigger.asSignal(); onLog = onLogTrigger.asSignal();
} }
public static function info(msg:Dynamic, ?pos:haxe.PosInfos) { public static function info(msg:Dynamic, ?pos:haxe.PosInfos) {
instance.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) { public static function warn(msg:Dynamic, ?pos:haxe.PosInfos) {
instance.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) { public static function error(msg:Dynamic, ?pos:haxe.PosInfos) {
instance.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) { public static function debug(msg:Dynamic, ?pos:haxe.PosInfos) {
#if debug #if debug
instance.log({level: Debug, message: Std.string(msg),time: 0},pos); log({level: Debug, message: Std.string(msg),time: 0},pos);
#end #end
} }
public static function silly(msg:Dynamic, ?pos:haxe.PosInfos) { public static function silly(msg:Dynamic, ?pos:haxe.PosInfos) {
instance.log({level: Silly, message: Std.string(msg),time: 0},pos); log({level: Silly, message: Std.string(msg),time: 0},pos);
} }
private function log(line: LogLine, ?pos:haxe.PosInfos) { private static function log(line: LogLine, ?pos:haxe.PosInfos) {
line.origin = pos.className; line.origin = pos.className;
logLines.push(line); logLines.push(line);
@@ -60,7 +59,7 @@ class Log {
#end #end
} }
public function getLines():ReadOnlyArray<LogLine> { public static function getLines():ReadOnlyArray<LogLine> {
return logLines; return logLines;
} }
} }

View File

@@ -20,33 +20,34 @@ class Net {
/** /**
Depends on: KernelEvents Depends on: KernelEvents
**/ **/
public static var instance:Net;
public static inline final BRODCAST_PORT:Int = 65533; public static inline final BRODCAST_PORT:Int = 65533;
public static inline final MESSAGE_TIMEOUT:Int = 3; public static inline final MESSAGE_TIMEOUT:Int = 3;
public static inline final DEFAULT_TTL:Int = 10; public static inline final DEFAULT_TTL:Int = 10;
public final networkID:NetworkID = OS.getComputerID(); public static final networkID:NetworkID = OS.getComputerID();
private final responseBus:Map<Int, Callback<Outcome<GenericPackage,Error>>> = new Map(); private static final responseBus:Map<Int, Callback<Outcome<GenericPackage,Error>>> = new Map();
private final protoHandlers:Map<String, Callback<GenericPackage>> = new Map(); private static final protoHandlers:Map<String, Callback<GenericPackage>> = new Map();
private var interfaces:Array<INetworkInterface>; private static var interfaces:Array<INetworkInterface>;
@:allow(kernel.Init) @:allow(kernel.Init)
private function new() { private static function init() {
this.interfaces = [for (e in Peripheral.instance.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?
this.interfaces.push(Loopback.instance); interfaces.push(Loopback.instance);
for (interf in interfaces){ for (interf in interfaces){
setupInterf(interf); setupInterf(interf);
} }
setupPingHandle(); setupPingHandle();
Routing.setup();
} }
private function setupPingHandle() { private static function setupPingHandle() {
this.registerProto("icmp", pack -> { registerProto("icmp", pack -> {
switch pack.data.type { switch pack.data.type {
case "ping": case "ping":
this.respondTo(pack, "pong"); respondTo(pack, "pong");
case "died": case "died":
// If we get a "died" message from a node when one of our packages ttl hits 0 // If we get a "died" message from a node when one of our packages ttl hits 0
// the `data.msgId` prop is the message id // the `data.msgId` prop is the message id
@@ -60,7 +61,7 @@ class Net {
}); });
} }
private function setupInterf(interf: INetworkInterface) { private static function setupInterf(interf: INetworkInterface) {
interf.onMessage.handle(e -> handle(e.pack,interf,e.dist)); interf.onMessage.handle(e -> handle(e.pack,interf,e.dist));
interf.listen(networkID); interf.listen(networkID);
interf.listen(BRODCAST_PORT); interf.listen(BRODCAST_PORT);
@@ -69,8 +70,8 @@ class Net {
/** /**
Called when a new package comes in. Called when a new package comes in.
**/ **/
private function handle(pack:GenericPackage,interf: INetworkInterface, ?dist: Float) { private static function handle(pack:GenericPackage,interf: INetworkInterface, ?dist: Float) {
if (pack.toID == this.networkID || pack.toID == Net.BRODCAST_PORT){ if (pack.toID == networkID || pack.toID == Net.BRODCAST_PORT){
switch pack.type { switch pack.type {
case Data(_) | DataNoResponse(_): case Data(_) | DataNoResponse(_):
// Let a local proccess handle it // Let a local proccess handle it
@@ -82,14 +83,14 @@ class Net {
} }
case RouteDiscover(_) | RouteDiscoverResponse(_) | RouteDiscoverUpdate(_): case RouteDiscover(_) | RouteDiscoverResponse(_) | RouteDiscoverUpdate(_):
// Delegate to Routing // Delegate to Routing
Routing.instance.handleRoutePackage(cast pack,interf); Routing.handleRoutePackage(cast pack,interf);
case GPSRequest | GPSResponse(_): case GPSRequest | GPSResponse(_):
if (dist == null) { if (dist == null) {
Log.silly("Got a GPS package but no distance was provided"); Log.silly("Got a GPS package but no distance was provided");
return; return;
} }
// Delegate to GPS // Delegate to GPS
GPS.instance.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. // New message received but its not ment for us. Forward if possible.
@@ -97,14 +98,14 @@ class Net {
} }
} }
private function generateMessageID():Int { private static function generateMessageID():Int {
return Std.random(2147483647); // TODO: better uniqe number return Std.random(2147483647); // TODO: better uniqe number
} }
/** /**
Send a message. Dont care if its reaches its destination nor it has a response. Send a message. Dont care if its reaches its destination nor it has a response.
**/ **/
public function sendAndForget(dest:Int, proto:String, data:Dynamic) { public static function sendAndForget(dest:Int, proto:String, data:Dynamic) {
var pack:GenericPackage = { var pack:GenericPackage = {
toID: dest, toID: dest,
fromID: networkID, fromID: networkID,
@@ -117,7 +118,7 @@ class Net {
sendRaw(pack); sendRaw(pack);
} }
private function forwardPackage(pack: GenericPackage) { private static function forwardPackage(pack: GenericPackage) {
if (pack.ttl == 0){ if (pack.ttl == 0){
if (pack.type.match(Data(_))) { if (pack.type.match(Data(_))) {
@@ -137,7 +138,7 @@ class Net {
} }
} }
public function respondTo(pack:GenericPackage, data:Dynamic) { public static function respondTo(pack:GenericPackage, data:Dynamic) {
if (pack.type.match(DataNoResponse(_))) { if (pack.type.match(DataNoResponse(_))) {
Log.warn("Responed to a no response package. Ignoring"); Log.warn("Responed to a no response package. Ignoring");
return; return;
@@ -151,7 +152,7 @@ class Net {
/** /**
Send to package to the localy register handler based on the proto Send to package to the localy register handler based on the proto
**/ **/
private function routeToProto(pack:GenericPackage) { private static function routeToProto(pack:GenericPackage) {
var proto = switch pack.type { var proto = switch pack.type {
case Data(proto): case Data(proto):
proto; proto;
@@ -173,20 +174,20 @@ class Net {
Just send the package to the right modem. Just send the package to the right modem.
Returns true if message was send Returns true if message was send
**/ **/
private function sendRaw(pack:GenericPackage): Bool { private static function sendRaw(pack:GenericPackage): Bool {
var route = Routing.instance.getRouteToID(pack.toID); var route = Routing.getRouteToID(pack.toID);
if (route == null){ if (route == null){
return false; return false;
} }
route.interf.send(route.rep,this.networkID,pack); route.interf.send(route.rep,networkID,pack);
return true; return true;
} }
/** /**
Send a message and wait for a response. Send a message and wait for a response.
**/ **/
public function sendAndAwait<T>(dest:NetworkID, proto:String, data:T):Promise<GenericPackage> { public static function sendAndAwait<T>(dest:NetworkID, proto:String, data:T):Promise<GenericPackage> {
return new Promise<GenericPackage>((resolve, reject) -> { return new Promise<GenericPackage>((resolve, reject) -> {
var pack:GenericPackage = { var pack:GenericPackage = {
toID: dest, toID: dest,
@@ -228,7 +229,7 @@ class Net {
}); });
} }
public function registerProto(proto:String, callback:Callback<GenericPackage>) { public static function registerProto(proto:String, callback:Callback<GenericPackage>) {
if (protoHandlers.exists(proto)) { if (protoHandlers.exists(proto)) {
// Failed. Handler already exist. // Failed. Handler already exist.
// TODO: return error // TODO: return error
@@ -238,16 +239,16 @@ class Net {
protoHandlers[proto] = callback; protoHandlers[proto] = callback;
} }
public function removeProto(proto:String) { public static function removeProto(proto:String) {
protoHandlers.remove(proto); protoHandlers.remove(proto);
} }
/** /**
Sends a ping package to the given id. Returns true if there was a response. Sends a ping package to the given id. Returns true if there was a response.
**/ **/
public function ping(toID: NetworkID): Promise<Noise> { public static function ping(toID: NetworkID): Promise<Noise> {
return new Promise<Noise>((resolve,reject)->{ return new Promise<Noise>((resolve,reject)->{
this.sendAndAwait(toID,"icmp",{type:"ping"}).handle(pack -> { sendAndAwait(toID,"icmp",{type:"ping"}).handle(pack -> {
switch pack { switch pack {
case Success(_): case Success(_):
resolve(Noise); resolve(Noise);
@@ -259,7 +260,7 @@ class Net {
}); });
} }
public function getActiveProtocols(): ReadOnlyArray<String> { public static function getActiveProtocols(): ReadOnlyArray<String> {
var arr = new Array<String>(); var arr = new Array<String>();
for (proto in protoHandlers.keys()) { for (proto in protoHandlers.keys()) {
@@ -270,7 +271,7 @@ class Net {
} }
@:allow(kernel.gps.GPS) @:allow(kernel.gps.GPS)
private function brodcastGPSRequest() { private static function brodcastGPSRequest() {
var pack: Package<Noise> = { var pack: Package<Noise> = {
fromID: networkID, fromID: networkID,
toID: Net.BRODCAST_PORT, toID: Net.BRODCAST_PORT,
@@ -280,9 +281,9 @@ class Net {
data: null, data: null,
}; };
for (modem in Peripheral.instance.getAllModems()) { for (modem in Peripheral.getAllModems()) {
if (!modem.isWireless()) continue; if (!modem.isWireless()) continue;
modem.send(Net.BRODCAST_PORT, Net.instance.networkID, pack); modem.send(Net.BRODCAST_PORT, networkID, pack);
} }
} }
} }

View File

@@ -51,9 +51,9 @@ enum PackageTypes {
} }
/** /**
Wrapper for `Net.instance.respondTo`. Wrapper for `Net.respondTo`.
**/ **/
public function respond(data:Dynamic) { public function respond(data:Dynamic) {
Net.instance.respondTo(this, data); Net.respondTo(this, data);
} }
} }

View File

@@ -20,24 +20,23 @@ class Routing {
/** /**
Depends on: Peripheral Depends on: Peripheral
**/ **/
public static var instance:Routing;
public static inline final UPDATE_WAIT_TIME:Float = 1; public static inline final UPDATE_WAIT_TIME:Float = 1;
public final onNewNeigbor:Signal<Int>; public static var onNewNeigbor(default, null):Signal<Int>;
private final onNewNeigborTrigger:SignalTrigger<NetworkID> = Signal.trigger(); private static final onNewNeigborTrigger:SignalTrigger<NetworkID> = Signal.trigger();
private final routingTable:Map<NetworkID, Route> = new Map(); private static final routingTable:Map<NetworkID, Route> = new Map();
private var routeUpdateInQueue:Bool = false; private static var routeUpdateInQueue:Bool = false;
@:allow(kernel.Init) @:allow(kernel.Init)
private function new() { private static function init() {
this.onNewNeigbor = this.onNewNeigborTrigger.asSignal(); onNewNeigbor = onNewNeigborTrigger.asSignal();
} }
@:allow(kernel.Init) @:allow(kernel.net.Net)
private function init() { private static function setup() {
routingTable.set(Net.instance.networkID, {interf: Loopback.instance, cost: 0, rep: Net.instance.networkID}); routingTable.set(Net.networkID, {interf: Loopback.instance, cost: 0, rep: Net.networkID});
brodcastRoutingTable(); brodcastRoutingTable();
} }
@@ -45,27 +44,27 @@ class Routing {
Prepares an brodcast of the current routing table. If a brodcast is already in queue it will be ignored. Prepares an brodcast of the current routing table. If a brodcast is already in queue it will be ignored.
After UPDATE_WAIT_TIME seconds the routing table will be brodcasted. This is done to prevent spamming the network. After UPDATE_WAIT_TIME seconds the routing table will be brodcasted. This is done to prevent spamming the network.
**/ **/
private function prepareRouteUpdate() { private static function prepareRouteUpdate() {
if (this.routeUpdateInQueue) { if (routeUpdateInQueue) {
return; return;
} }
this.routeUpdateInQueue = true; routeUpdateInQueue = true;
new Timer(UPDATE_WAIT_TIME, () -> { new Timer(UPDATE_WAIT_TIME, () -> {
brodcastRoutingTable(); brodcastRoutingTable();
this.routeUpdateInQueue = false; routeUpdateInQueue = false;
}); });
} }
/** /**
Brodcast the current routing table to all peers. Brodcast the current routing table to all peers.
**/ **/
private function brodcastRoutingTable() { private static function brodcastRoutingTable() {
var pack = newRoutDiscoverPackage(); var pack = newRoutDiscoverPackage();
for (modem in Peripheral.instance.getAllModems()) { for (modem in Peripheral.getAllModems()) {
modem.send(Net.BRODCAST_PORT, Net.instance.networkID, pack); modem.send(Net.BRODCAST_PORT, Net.networkID, pack);
} }
} }
@@ -73,7 +72,7 @@ class Routing {
Handle incomming packages that involve route discovery. Handle incomming packages that involve route discovery.
**/ **/
@:allow(kernel.net.Net) @:allow(kernel.net.Net)
private function handleRoutePackage(pack:Package<Noise>, interf:INetworkInterface):Void { private static function handleRoutePackage(pack:Package<Noise>, interf:INetworkInterface):Void {
addPossibleRoute(pack.fromID, interf, 0, pack.fromID); addPossibleRoute(pack.fromID, interf, 0, pack.fromID);
var shouldRespond:Bool = switch pack.type { var shouldRespond:Bool = switch pack.type {
@@ -104,22 +103,22 @@ class Routing {
// Respond to peer // Respond to peer
var response:Package<Noise> = { var response:Package<Noise> = {
toID: pack.fromID, toID: pack.fromID,
fromID: Net.instance.networkID, fromID: Net.networkID,
msgID: null, msgID: null,
type: RouteDiscoverResponse(genRouteList()), type: RouteDiscoverResponse(genRouteList()),
data: null, data: null,
ttl: 0, // Prevent forwarding ttl: 0, // Prevent forwarding
} }
interf.send(response.toID, Net.instance.networkID, response); interf.send(response.toID, Net.networkID, response);
} }
/** /**
Generate a list of routes to send to a peer based on the current routing table. Generate a list of routes to send to a peer based on the current routing table.
**/ **/
private function genRouteList():Array<{id:NetworkID, cost:Int}> { private static function genRouteList():Array<{id:NetworkID, cost:Int}> {
var routes:Array<{id:NetworkID, cost:Int}> = []; var routes:Array<{id:NetworkID, cost:Int}> = [];
for (k => v in this.routingTable) { for (k => v in routingTable) {
routes.push({ routes.push({
id: k, id: k,
cost: v.cost cost: v.cost
@@ -128,12 +127,12 @@ class Routing {
return routes; return routes;
} }
private function newRoutDiscoverPackage():Package<Noise> { private static function newRoutDiscoverPackage():Package<Noise> {
var pack:Package<Noise> = { var pack:Package<Noise> = {
type: RouteDiscover(genRouteList()), type: RouteDiscover(genRouteList()),
toID: Net.BRODCAST_PORT, toID: Net.BRODCAST_PORT,
msgID: null, msgID: null,
fromID: Net.instance.networkID, fromID: Net.networkID,
data: null, data: null,
ttl: 0, // Prevent forwarding ttl: 0, // Prevent forwarding
} }
@@ -145,31 +144,31 @@ class Routing {
Called when a route to a client has been disoverd. Called when a route to a client has been disoverd.
Its possible to be called multiple times with the same id but different addr. Its possible to be called multiple times with the same id but different addr.
**/ **/
private function addPossibleRoute(toID:Int, interf:INetworkInterface, cost:Int, rep:NetworkID) { private static function addPossibleRoute(toID:Int, interf:INetworkInterface, cost:Int, rep:NetworkID) {
if (toID == Net.instance.networkID) { if (toID == Net.networkID) {
return; return;
} }
var fullCost = cost + interf.getBaseRoutingCost(); var fullCost = cost + interf.getBaseRoutingCost();
if (this.routingTable.exists(toID)) { if (routingTable.exists(toID)) {
if (this.routingTable[toID].cost > fullCost) { if (routingTable[toID].cost > fullCost) {
this.routingTable[toID] = {interf: interf, cost: cost + interf.getBaseRoutingCost(), rep: rep}; routingTable[toID] = {interf: interf, cost: cost + interf.getBaseRoutingCost(), rep: rep};
this.prepareRouteUpdate(); prepareRouteUpdate();
} }
} else { } else {
this.routingTable[toID] = {interf: interf, cost: cost + interf.getBaseRoutingCost(), rep: rep}; routingTable[toID] = {interf: interf, cost: cost + interf.getBaseRoutingCost(), rep: rep};
this.onNewNeigborTrigger.trigger(toID); onNewNeigborTrigger.trigger(toID);
this.prepareRouteUpdate(); prepareRouteUpdate();
} }
} }
public function getRouteToID(networkID:NetworkID):{interf:INetworkInterface, rep:NetworkID} { public static function getRouteToID(networkID:NetworkID):{interf:INetworkInterface, rep:NetworkID} {
if (networkID == Net.instance.networkID) { if (networkID == Net.networkID) {
return {interf: Loopback.instance, rep: Net.instance.networkID}; return {interf: Loopback.instance, rep: Net.networkID};
} }
var route:Null<Route> = this.routingTable[networkID]; var route:Null<Route> = routingTable[networkID];
if (route == null) { if (route == null) {
return null; return null;
@@ -178,7 +177,7 @@ class Routing {
} }
} }
public function getRouteTable():Map<NetworkID, Route> { public static function getRouteTable():Map<NetworkID, Route> {
return this.routingTable; return routingTable;
} }
} }

View File

@@ -22,13 +22,13 @@ class Drive implements IPeripheral {
this.onDiskInsert = this.onDiskInsertTrigger.asSignal(); this.onDiskInsert = this.onDiskInsertTrigger.asSignal();
this.onDiskEject = this.onDiskEjectTrigger.asSignal(); this.onDiskEject = this.onDiskEjectTrigger.asSignal();
KernelEvents.instance.onDisk.handle((addr) ->{ KernelEvents.onDisk.handle((addr) ->{
if (addr == this.addr){ if (addr == this.addr){
this.onDiskInsertTrigger.trigger(null); this.onDiskInsertTrigger.trigger(null);
} }
}); });
KernelEvents.instance.onDiskEject.handle((addr)->{ KernelEvents.onDiskEject.handle((addr)->{
if (addr == this.addr){ if (addr == this.addr){
this.onDiskEjectTrigger.trigger(null); this.onDiskEjectTrigger.trigger(null);
} }

View File

@@ -22,7 +22,7 @@ class Modem implements INetworkInterface implements IPeripheral {
this.native = Peripheral.wrap(addr); this.native = Peripheral.wrap(addr);
this.addr = addr; this.addr = addr;
KernelEvents.instance.onModemMessage.handle(params ->{ KernelEvents.onModemMessage.handle(params ->{
try{ try{
if (params.addr == this.addr){ if (params.addr == this.addr){
var pack:GenericPackage = { var pack:GenericPackage = {

View File

@@ -11,24 +11,15 @@ using tink.CoreApi;
Class responseable for retrieving peripherals. Class responseable for retrieving peripherals.
**/ **/
class Peripheral { class Peripheral {
/** public static function getAllAddresses(): Array<String> {
Depends on: KernelEvents
**/
public static var instance:Peripheral;
@:allow(kernel.Init)
private function new() {
}
public function getAllAddresses(): Array<String> {
return cc.Peripheral.getNames().toArray(); return cc.Peripheral.getNames().toArray();
} }
public function isPresent(addr: String): Bool { public static function isPresent(addr: String): Bool {
return cc.Peripheral.isPresent(addr); return cc.Peripheral.isPresent(addr);
} }
public function getTypes(addr: String): Array<String> { public static function getTypes(addr: String): Array<String> {
if (!cc.Peripheral.isPresent(addr)) { if (!cc.Peripheral.isPresent(addr)) {
return []; return [];
} }
@@ -36,11 +27,11 @@ class Peripheral {
return cc.Peripheral.getType(addr).toArray(); return cc.Peripheral.getType(addr).toArray();
} }
public function findAddrByType(type: String): Array<String> { public static function findAddrByType(type: String): Array<String> {
return getAllAddresses().filter(addr -> getTypes(addr).contains(type)); return getAllAddresses().filter(addr -> getTypes(addr).contains(type));
} }
private function safeGetAddr(addr: String, type: String): Null<String> { private static function safeGetAddr(addr: String, type: String): Null<String> {
if (!isPresent(addr)) { if (!isPresent(addr)) {
return null; return null;
} }
@@ -53,7 +44,7 @@ class Peripheral {
return addr; return addr;
} }
public 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)) { if (!isPresent(addr)) {
return null; return null;
} }
@@ -76,7 +67,7 @@ class Peripheral {
Cast peripheral to a specific type. Cast peripheral to a specific type.
This is a temporary solution, maybe forever. This is a temporary solution, maybe forever.
**/ **/
public function getFromType(addr: String, type: String): Null<IPeripheral> { public static function getFromType(addr: String, type: String): Null<IPeripheral> {
switch (type){ switch (type){
case Computer.TYPE_NAME: case Computer.TYPE_NAME:
return getComputer(addr); return getComputer(addr);
@@ -97,69 +88,69 @@ class Peripheral {
return null; return null;
} }
public function getScreen(addr: String): Null<Screen> { public static function getScreen(addr: String): Null<Screen> {
var addr = safeGetAddr(addr, Screen.TYPE_NAME); var addr = safeGetAddr(addr, Screen.TYPE_NAME);
if (addr == null) return null; if (addr == null) return null;
return new Screen(addr); return new Screen(addr);
} }
public function getAllScreens(): Array<Screen> { public static function getAllScreens(): Array<Screen> {
return [ for (addr in findAddrByType(Screen.TYPE_NAME)) new Screen(addr)]; return [ for (addr in findAddrByType(Screen.TYPE_NAME)) new Screen(addr)];
} }
public function getModem(addr: String): Null<Modem> { public static function getModem(addr: String): Null<Modem> {
var addr = safeGetAddr(addr, Modem.TYPE_NAME); var addr = safeGetAddr(addr, Modem.TYPE_NAME);
if (addr == null) return null; if (addr == null) return null;
return new Modem(addr); return new Modem(addr);
} }
public function getAllModems(): Array<Modem> { public static function getAllModems(): Array<Modem> {
return [ for (addr in findAddrByType(Modem.TYPE_NAME)) new Modem(addr)]; return [ for (addr in findAddrByType(Modem.TYPE_NAME)) new Modem(addr)];
} }
public function getDrive(addr: String): Null<Drive> { public static function getDrive(addr: String): Null<Drive> {
var addr = safeGetAddr(addr, Drive.TYPE_NAME); var addr = safeGetAddr(addr, Drive.TYPE_NAME);
if (addr == null) return null; if (addr == null) return null;
return new Drive(addr); return new Drive(addr);
} }
public function getAllDrives(): Array<Drive> { public static function getAllDrives(): Array<Drive> {
return [ for (addr in findAddrByType(Drive.TYPE_NAME)) new Drive(addr)]; return [ for (addr in findAddrByType(Drive.TYPE_NAME)) new Drive(addr)];
} }
public function getRedstone(side: String): Redstone { public static function getRedstone(side: String): Redstone {
// TODO: maybe handle restone differently to not duplicate event listeners // TODO: maybe handle restone differently to not duplicate event listeners
return new Redstone(side); return new Redstone(side);
} }
public function getPrinter(addr: String):Null<Printer> { public static function getPrinter(addr: String):Null<Printer> {
var addr = safeGetAddr(addr, Printer.TYPE_NAME); var addr = safeGetAddr(addr, Printer.TYPE_NAME);
if (addr == null) return null; if (addr == null) return null;
return new Printer(addr); return new Printer(addr);
} }
public function getAllPrinters(): Array<Printer> { public static function getAllPrinters(): Array<Printer> {
return [ for (addr in findAddrByType(Printer.TYPE_NAME)) new Printer(addr)]; return [ for (addr in findAddrByType(Printer.TYPE_NAME)) new Printer(addr)];
} }
public function getEnergyStorage(addr: String): Null<EnergyStorage> { public static function getEnergyStorage(addr: String): Null<EnergyStorage> {
var addr = safeGetAddr(addr, EnergyStorage.TYPE_NAME); var addr = safeGetAddr(addr, EnergyStorage.TYPE_NAME);
if (addr == null) return null; if (addr == null) return null;
return new EnergyStorage(addr); return new EnergyStorage(addr);
} }
public function getAllEnergyStorages(): Array<EnergyStorage> { public static function getAllEnergyStorages(): Array<EnergyStorage> {
return [ for (addr in findAddrByType(EnergyStorage.TYPE_NAME)) new EnergyStorage(addr)]; return [ for (addr in findAddrByType(EnergyStorage.TYPE_NAME)) new EnergyStorage(addr)];
} }
public function getComputer(addr: String): Null<Computer> { public static function getComputer(addr: String): Null<Computer> {
var addr = safeGetAddr(addr, Computer.TYPE_NAME); var addr = safeGetAddr(addr, Computer.TYPE_NAME);
if (addr == null) return null; if (addr == null) return null;
return new Computer(addr); return new Computer(addr);
} }
public function getAllComputers(): Array<Computer> { public static function getAllComputers(): Array<Computer> {
return [ for (addr in findAddrByType(Computer.TYPE_NAME)) new Computer(addr)]; return [ for (addr in findAddrByType(Computer.TYPE_NAME)) new Computer(addr)];
} }
} }

View File

@@ -63,7 +63,7 @@ class Redstone implements IPeripheral implements IExportable {
updateState(); updateState();
KernelEvents.instance.onRedstone.handle(()->{ KernelEvents.onRedstone.handle(()->{
if ((this.getAnalogInput() != this.analogInputState) || (this.bundleInputState != this.getBundledInput())){ if ((this.getAnalogInput() != this.analogInputState) || (this.bundleInputState != this.getBundledInput())){
updateState(); updateState();
this.onChangeTrigger.trigger(null); this.onChangeTrigger.trigger(null);

View File

@@ -26,7 +26,7 @@ class Screen implements TermWriteable implements IPeripheral {
this.nativ = Peripheral.wrap(addr); this.nativ = Peripheral.wrap(addr);
this.addr = addr; this.addr = addr;
KernelEvents.instance.onMonitorResize.handle(addr -> { KernelEvents.onMonitorResize.handle(addr -> {
if (addr == this.addr) { if (addr == this.addr) {
onResizeTrigger.trigger(getSize()); onResizeTrigger.trigger(getSize());
} }

View File

@@ -63,13 +63,13 @@ class ProcessHandle {
} }
public function createBufferdWindowContext(): WindowContext { public function createBufferdWindowContext(): WindowContext {
var ctx = WindowManager.instance.createNewContext(); var ctx = WindowManager.createNewContext();
this.windowContexts.push(ctx); this.windowContexts.push(ctx);
return 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.instance.createNewStatelessContext(); var ctx = WindowManager.createNewStatelessContext();
this.windowContexts.push(ctx.ctx); this.windowContexts.push(ctx.ctx);
return ctx; return ctx;
} }

View File

@@ -21,7 +21,7 @@ class Service {
} }
public function start() { public function start() {
var bin = BinStore.instance.getBinByAlias(this.binName); var bin = BinStore.getBinByAlias(this.binName);
if (bin == null){ if (bin == null){
throw new Error('Bin ${this.binName} not found'); throw new Error('Bin ${this.binName} not found');

View File

@@ -7,20 +7,18 @@ import lib.KVStore;
using tink.CoreApi; using tink.CoreApi;
class ServiceManager { class ServiceManager {
public static var instance: ServiceManager; private static final services:Map<String,Service> = new Map();
private final services:Map<String,Service> = new Map();
@:allow(kernel.Init) @:allow(kernel.Init)
private function new() { private static function init() {
this.startAllEnabled(); startAllEnabled();
} }
/** /**
Add a service to be automatically started. Add a service to be automatically started.
**/ **/
public function enable(name: String) { public static function enable(name: String) {
if (!this.services.exists(name)){ if (!services.exists(name)){
return; // Service must be started return; // Service must be started
} }
@@ -36,7 +34,7 @@ class ServiceManager {
/** /**
Remove a service from being automatically started. Remove a service from being automatically started.
**/ **/
private function disable(name: String) { private static function disable(name: String) {
var store = KVStore.getStoreForClass(); var store = KVStore.getStoreForClass();
var enabled: Array<String> = store.get("enabled"); var enabled: Array<String> = store.get("enabled");
var index = enabled.indexOf(name); var index = enabled.indexOf(name);
@@ -48,15 +46,15 @@ class ServiceManager {
store.save(); store.save();
} }
private function startAllEnabled() { private static function startAllEnabled() {
var store = KVStore.getStoreForClass(); var store = KVStore.getStoreForClass();
var enabled: Array<String> = store.get("enabled",[]); var enabled: Array<String> = store.get("enabled",[]);
for (name in enabled){ for (name in enabled){
this.start(name); start(name);
} }
} }
private function load(name: String): Null<Service> { private static function load(name: String): Null<Service> {
var store = new KVStore('service/${name}'); var store = new KVStore('service/${name}');
store.load(); store.load();
if (!store.exists("service")){ if (!store.exists("service")){
@@ -66,12 +64,12 @@ class ServiceManager {
return store.get("service"); return store.get("service");
} }
public function register(name: String, binName: String,args: Array<String>): Outcome<Noise,String> { public static function register(name: String, binName: String,args: Array<String>): Outcome<Noise,String> {
if (BinStore.instance.getBinByAlias(binName) == null){ if (BinStore.getBinByAlias(binName) == null){
return Failure("bin not found"); return Failure("bin not found");
} }
if (this.load(name) != null){ if (load(name) != null){
return Failure("service already exists"); return Failure("service already exists");
} }
@@ -85,8 +83,8 @@ class ServiceManager {
return Success(Noise); return Success(Noise);
} }
public function unregister(name: String): Outcome<Noise,String> { public static function unregister(name: String): Outcome<Noise,String> {
if (this.services.exists(name)){ if (services.exists(name)){
return Failure("service is running"); return Failure("service is running");
} }
@@ -95,48 +93,48 @@ class ServiceManager {
return Success(Noise); return Success(Noise);
} }
public function start(name: String): Outcome<Noise,String> { public static function start(name: String): Outcome<Noise,String> {
var service = this.load(name); var service = load(name);
if (service == null){ if (service == null){
return Failure("service not found"); return Failure("service not found");
} }
service.start(); service.start();
this.services.set(name,service); services.set(name,service);
Log.info('Service ${name} started'); Log.info('Service ${name} started');
return Success(Noise); return Success(Noise);
} }
public function stop(name: String): Outcome<Noise,String> { public static function stop(name: String): Outcome<Noise,String> {
if (!this.services.exists(name)){ if (!services.exists(name)){
return Failure("service not found"); return Failure("service not found");
} }
var service = this.services.get(name); var service = services.get(name);
service.stop(); service.stop();
this.services.remove(name); services.remove(name);
Log.info('Service ${name} stopped'); Log.info('Service ${name} stopped');
return Success(Noise); return Success(Noise);
} }
public function listRunning(): Array<String> { public static function listRunning(): Array<String> {
var running = []; var running = [];
for (name in this.services.keys()){ for (name in services.keys()){
running.push(name); running.push(name);
} }
return running; return running;
} }
public function get(name: String): Null<Dynamic> { public static function get(name: String): Null<Dynamic> {
if (!this.services.exists(name)){ if (!services.exists(name)){
return null; return null;
} }
// TODO: Maybe there is a way to check types here? // TODO: Maybe there is a way to check types here?
var srv = this.services.get(name); var srv = services.get(name);
return srv.ps; return srv.ps;
} }

View File

@@ -36,42 +36,42 @@ class Turtle {
public function forward():Outcome<Noise, String> { public function forward():Outcome<Noise, String> {
var r = cc.Turtle.forward(); var r = cc.Turtle.forward();
var r2 = conterToOutcome(r); var r2 = conterToOutcome(r);
if (r2.isSuccess()) INS.instance.moveForward(); if (r2.isSuccess()) INS.moveForward();
return r2; return r2;
} }
public function back():Outcome<Noise, String> { public function back():Outcome<Noise, String> {
var r = cc.Turtle.back(); var r = cc.Turtle.back();
var r2 = conterToOutcome(r); var r2 = conterToOutcome(r);
if (r2.isSuccess()) INS.instance.moveBackward(); if (r2.isSuccess()) INS.moveBackward();
return r2; return r2;
} }
public function up():Outcome<Noise, String> { public function up():Outcome<Noise, String> {
var r = cc.Turtle.up(); var r = cc.Turtle.up();
var r2 = conterToOutcome(r); var r2 = conterToOutcome(r);
if (r2.isSuccess()) INS.instance.moveUp(); if (r2.isSuccess()) INS.moveUp();
return r2; return r2;
} }
public function down():Outcome<Noise, String> { public function down():Outcome<Noise, String> {
var r = cc.Turtle.down(); var r = cc.Turtle.down();
var r2 = conterToOutcome(r); var r2 = conterToOutcome(r);
if (r2.isSuccess()) INS.instance.moveDown(); if (r2.isSuccess()) INS.moveDown();
return r2; return r2;
} }
public function turnLeft():Outcome<Noise, String> { public function turnLeft():Outcome<Noise, String> {
var r = cc.Turtle.turnLeft(); var r = cc.Turtle.turnLeft();
var r2 = conterToOutcome(r); var r2 = conterToOutcome(r);
if (r2.isSuccess()) INS.instance.turnRight(); if (r2.isSuccess()) INS.turnRight();
return r2; return r2;
} }
public function turnRight():Outcome<Noise, String> { public function turnRight():Outcome<Noise, String> {
var r = cc.Turtle.turnRight(); var r = cc.Turtle.turnRight();
var r2 = conterToOutcome(r); var r2 = conterToOutcome(r);
if (r2.isSuccess()) INS.instance.turnRight(); if (r2.isSuccess()) INS.turnRight();
return r2; return r2;
} }

View File

@@ -14,13 +14,12 @@ class WindowManager {
/** /**
Depends on: KernelEvents, Peripheral Depends on: KernelEvents, Peripheral
**/ **/
public static var instance:WindowManager; private static var currentMainContext:WindowContext;
private var currentMainContext:WindowContext; private static final outputMap:Map<String, WindowContext> = new Map();
private final outputMap:Map<String, WindowContext> = new Map();
@:allow(kernel.Init) @:allow(kernel.Init)
private function new() { private static function init() {
KernelEvents.instance.onKey.handle(params -> { KernelEvents.onKey.handle(params -> {
if (currentMainContext != null) { if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){ if (currentMainContext.eventDelegate != null){
var foo = currentMainContext.eventDelegate.getEventHandlers(); var foo = currentMainContext.eventDelegate.getEventHandlers();
@@ -31,7 +30,7 @@ class WindowManager {
} }
}); });
KernelEvents.instance.onKeyUp.handle(keyCode -> { KernelEvents.onKeyUp.handle(keyCode -> {
if (currentMainContext != null) { if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){ if (currentMainContext.eventDelegate != null){
var foo = currentMainContext.eventDelegate.getEventHandlers(); var foo = currentMainContext.eventDelegate.getEventHandlers();
@@ -42,7 +41,7 @@ class WindowManager {
} }
}); });
KernelEvents.instance.onMouseClick.handle(params -> { KernelEvents.onMouseClick.handle(params -> {
if (currentMainContext != null) { if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){ if (currentMainContext.eventDelegate != null){
var foo = currentMainContext.eventDelegate.getEventHandlers(); var foo = currentMainContext.eventDelegate.getEventHandlers();
@@ -53,7 +52,7 @@ class WindowManager {
} }
}); });
KernelEvents.instance.onMouseDrag.handle(params -> { KernelEvents.onMouseDrag.handle(params -> {
if (currentMainContext != null) { if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){ if (currentMainContext.eventDelegate != null){
var foo = currentMainContext.eventDelegate.getEventHandlers(); var foo = currentMainContext.eventDelegate.getEventHandlers();
@@ -64,7 +63,7 @@ class WindowManager {
} }
}); });
KernelEvents.instance.onMouseScroll.handle(params -> { KernelEvents.onMouseScroll.handle(params -> {
if (currentMainContext != null) { if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){ if (currentMainContext.eventDelegate != null){
var foo = currentMainContext.eventDelegate.getEventHandlers(); var foo = currentMainContext.eventDelegate.getEventHandlers();
@@ -75,7 +74,7 @@ class WindowManager {
} }
}); });
KernelEvents.instance.onMouseUp.handle(params -> { KernelEvents.onMouseUp.handle(params -> {
if (currentMainContext != null) { if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){ if (currentMainContext.eventDelegate != null){
var foo = currentMainContext.eventDelegate.getEventHandlers(); var foo = currentMainContext.eventDelegate.getEventHandlers();
@@ -86,7 +85,7 @@ class WindowManager {
} }
}); });
KernelEvents.instance.onPaste.handle(text -> { KernelEvents.onPaste.handle(text -> {
if (currentMainContext != null) { if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){ if (currentMainContext.eventDelegate != null){
var foo = currentMainContext.eventDelegate.getEventHandlers(); var foo = currentMainContext.eventDelegate.getEventHandlers();
@@ -97,11 +96,11 @@ class WindowManager {
} }
}); });
KernelEvents.instance.onMonitorTouch.handle(params -> { KernelEvents.onMonitorTouch.handle(params -> {
// TODO // TODO
}); });
KernelEvents.instance.onChar.handle(char -> { KernelEvents.onChar.handle(char -> {
if (currentMainContext != null) { if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){ if (currentMainContext.eventDelegate != null){
var foo = currentMainContext.eventDelegate.getEventHandlers(); var foo = currentMainContext.eventDelegate.getEventHandlers();
@@ -116,25 +115,25 @@ class WindowManager {
/** /**
Same as createNewBufferedContext because it is the most simple context. Same as createNewBufferedContext because it is the most simple context.
**/ **/
public function createNewContext():WindowContext { public static function createNewContext():WindowContext {
return createNewBufferedContext(); return createNewBufferedContext();
} }
public function createNewBufferedContext():WindowContext { public static function createNewBufferedContext():WindowContext {
var newContext = new WindowContext(new BufferedVirtualTermWriter()); var newContext = new WindowContext(new BufferedVirtualTermWriter());
return newContext; return newContext;
} }
public 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 writer = new StatelessVirtualTermWriter();
var newContext = new WindowContext(writer); var newContext = new WindowContext(writer);
return {ctx: newContext, setRenderFunc: writer.setRenderFunc, requestRender: writer.requestRender}; return {ctx: newContext, setRenderFunc: writer.setRenderFunc, requestRender: writer.requestRender};
} }
public function getOutputs():ReadOnlyArray<String> { public static function getOutputs():ReadOnlyArray<String> {
var arr = Peripheral.instance.getAllScreens().map(screen -> return screen.getAddr()); var arr = Peripheral.getAllScreens().map(screen -> return screen.getAddr());
arr.push("main"); arr.push("main");
return arr; return arr;
} }
@@ -142,13 +141,13 @@ class WindowManager {
/** /**
Move context to output. If output is "main", context will be moved to main screen. Move context to output. If output is "main", context will be moved to main screen.
**/ **/
public function focusContextToOutput(context:WindowContext, output:String) { public static function focusContextToOutput(context:WindowContext, output:String) {
var target:TermWriteable; var target:TermWriteable;
if (output == "main") { if (output == "main") {
target = MainTerm.instance; target = MainTerm.instance;
currentMainContext = context; currentMainContext = context;
} else { } else {
target = Peripheral.instance.getScreen(output); target = Peripheral.getScreen(output);
if (target == null) { if (target == null) {
// output target not found // output target not found
@@ -165,7 +164,7 @@ class WindowManager {
context.enable(); context.enable();
} }
public function getContextByPID(pid: PID): ReadOnlyArray<WindowContext> { public static function getContextByPID(pid: PID): ReadOnlyArray<WindowContext> {
var handle = ProcessManager.getProcess(pid); var handle = ProcessManager.getProcess(pid);
if (handle == null) { if (handle == null) {
return []; return [];

View File

@@ -39,13 +39,13 @@ class Debug {
#if Debug #if Debug
public static function printKernelEventsCount(){ public static function printKernelEventsCount(){
KernelEvents.instance.printListenerCount(); KernelEvents.printListenerCount();
} }
#end #end
#if webconsole #if webconsole
public static function printWeb(msg:String) { public static function printWeb(msg:String) {
HTTP.request("http://127.0.0.1:8080/"+Net.instance.networkID,msg); HTTP.request("http://127.0.0.1:8080/"+Net.networkID,msg);
} }
#end #end
} }

View File

@@ -41,10 +41,10 @@ class HomeContext {
public function run() { public function run() {
// Create main terminal context // Create main terminal context
var stateless = WindowManager.instance.createNewStatelessContext(); var stateless = WindowManager.createNewStatelessContext();
ctx = stateless.ctx; ctx = stateless.ctx;
requestRender = stateless.requestRender; requestRender = stateless.requestRender;
WindowManager.instance.focusContextToOutput(ctx, "main"); WindowManager.focusContextToOutput(ctx, "main");
renderer = new RootElement(); renderer = new RootElement();
renderer.setTitle("Home"); renderer.setTitle("Home");
@@ -54,7 +54,7 @@ class HomeContext {
requestRender(); requestRender();
// Register global key bindings to react to main terminal // Register global key bindings to react to main terminal
KernelEvents.instance.onKey.handle(e -> { KernelEvents.onKey.handle(e -> {
// Is HOME pressed? // Is HOME pressed?
// TODO: remove magic number // TODO: remove magic number
if (e.keyCode == 268) { if (e.keyCode == 268) {
@@ -85,14 +85,14 @@ class HomeContext {
private function focusContext(id:Int) { private function focusContext(id:Int) {
if (workspaces.exists(id)) { if (workspaces.exists(id)) {
WindowManager.instance.focusContextToOutput(workspaces[id], selectedOutput); WindowManager.focusContextToOutput(workspaces[id], selectedOutput);
currentWorkspace = id; currentWorkspace = id;
} }
} }
private function focusMainTerm() { private function focusMainTerm() {
requestRender(); requestRender();
WindowManager.instance.focusContextToOutput(ctx, "main"); WindowManager.focusContextToOutput(ctx, "main");
currentWorkspace = -1; currentWorkspace = -1;
} }
@@ -105,7 +105,7 @@ class HomeContext {
} }
private function spawnPs(binName: String) { private function spawnPs(binName: String) {
var bin = BinStore.instance.getBinByAlias(binName); var bin = BinStore.getBinByAlias(binName);
if (bin == null) { if (bin == null) {
Log.error('Could not find bin: ${binName}'); Log.error('Could not find bin: ${binName}');
@@ -116,7 +116,7 @@ class HomeContext {
var pid = ProcessManager.run(ps, {}); var pid = ProcessManager.run(ps, {});
var lastContextID = -1; var lastContextID = -1;
for ( ctx in WindowManager.instance.getContextByPID(pid)){ for ( ctx in WindowManager.getContextByPID(pid)){
lastContextID = addContextNextWorkspace(ctx); lastContextID = addContextNextWorkspace(ctx);
} }
@@ -131,7 +131,7 @@ class HomeContext {
} }
private function cycleOutput() { private function cycleOutput() {
var screenAddr = Peripheral.instance.findAddrByType(Screen.TYPE_NAME); var screenAddr = Peripheral.findAddrByType(Screen.TYPE_NAME);
if (selectedOutputIndex == -1) { if (selectedOutputIndex == -1) {
selectedOutputIndex = 0; selectedOutputIndex = 0;
@@ -159,13 +159,13 @@ class HomeContext {
for (i in 0...listedApps.length) { for (i in 0...listedApps.length) {
children.push(new TextElement( children.push(new TextElement(
'Add ${BinStore.instance.getNameByAlias(listedApps[i])}', 'Add ${BinStore.getNameByAlias(listedApps[i])}',
{uiEvents: {onClick: this.spawnPs.bind(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.instance.shutdown}})); children.push(new TextElement('Exit', {style: {bgColor: Red}, uiEvents: {onClick: KernelEvents.shutdown}}));
renderer.setChildren(children); renderer.setChildren(children);

View File

@@ -17,7 +17,7 @@ class RessourceNames {
var payload: GetRequest = {name: name, type: "get"}; var payload: GetRequest = {name: name, type: "get"};
return Net.instance.sendAndAwait( return Net.sendAndAwait(
controllerID, controllerID,
SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO, SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO,
payload payload
@@ -36,7 +36,7 @@ class RessourceNames {
var payload: RegisterRequest = {name: name, netID: netID, type: "register"}; var payload: RegisterRequest = {name: name, netID: netID, type: "register"};
return Net.instance.sendAndAwait( return Net.sendAndAwait(
controllerID, controllerID,
SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO, SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO,
payload payload
@@ -56,7 +56,7 @@ class RessourceNames {
var payload: UnregisterRequest = {name: name, type: "unregister"}; var payload: UnregisterRequest = {name: name, type: "unregister"};
return Net.instance.sendAndAwait( return Net.sendAndAwait(
controllerID, controllerID,
SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO, SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO,
payload payload
@@ -68,7 +68,7 @@ class RessourceNames {
var payload: ListRequest = {type: "list"}; var payload: ListRequest = {type: "list"};
return Net.instance.sendAndAwait( return Net.sendAndAwait(
controllerID, controllerID,
SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO, SiteRessourceController.SITE_CONTROLLER_RESSOURCE_MANAGER_PROTO,
payload payload

View File

@@ -15,7 +15,7 @@ class Import {
} }
private static function performRequest(netID: NetworkID, request: Request): Promise<Response> { private static function performRequest(netID: NetworkID, request: Request): Promise<Response> {
return Net.instance.sendAndAwait(netID,"res",request).map((response)->{ return Net.sendAndAwait(netID,"res",request).map((response)->{
switch (response){ switch (response){
case Success(data): case Success(data):
return Success(cast (data.data, Response)); return Success(cast (data.data, Response));

View File

@@ -71,7 +71,7 @@ class RPC {
} }
return macro { return macro {
kernel.net.Net.instance.registerProto($v{proto},(pack)->{ kernel.net.Net.registerProto($v{proto},(pack)->{
$a{exprs} $a{exprs}
}); });
}; };

View File

@@ -14,7 +14,7 @@ abstract class RPCBase {
} }
private function _performRequest(func: String, args: Array<Dynamic>):Promise<Dynamic> { private function _performRequest(func: String, args: Array<Dynamic>):Promise<Dynamic> {
return Net.instance.sendAndAwait(id, this._proto, { return Net.sendAndAwait(id, this._proto, {
func: func, func: func,
// args: args // args: args
}).map((res) -> { }).map((res) -> {

21
src/startup.lua Normal file
View File

@@ -0,0 +1,21 @@
-- Check for startup enable flag
if redstone.getInput("top") then
local fd = fs.open("/haxe.lua", "r")
local haxe = fd.readAll()
fd.close()
local make = dofile("rom/modules/main/cc/require.lua").make
local env = {}
env.require, env.package = make(env, "/")
env = setmetatable(env, { __index = _G })
local f,err = load(haxe,"Haxe",nil,env)
if err then
print("Error loading Haxe: " .. err)
else
f()
os.reboot()
end
end