BIG FORMATING COMMIT

This commit is contained in:
2023-07-30 15:55:22 +02:00
parent 088fce0aaa
commit 91972107eb
103 changed files with 1610 additions and 1585 deletions

View File

@@ -2,8 +2,8 @@ package kernel;
@:keep
class DCEHack {
// Dont actually call this
public static function load():Array<kernel.ps.Process>{
macros.DCEHack.dceGenerateCreate();
}
// Dont actually call this
public static function load():Array<kernel.ps.Process> {
macros.DCEHack.dceGenerateCreate();
}
}

View File

@@ -3,22 +3,26 @@ package kernel;
import cc.OS;
/**
Make sure that a function is called at the end of the current event loop.
Like setTimeout(func, 0) in JavaScript.
Make sure that a function is called at the end of the current event loop.
Like setTimeout(func, 0) in JavaScript.
**/
class EndOfLoop {
private static var backlog:Array<Void -> Void> = [];
private static var isQueued = false;
private static var backlog:Array<Void->Void> = [];
private static var isQueued = false;
public static function endOfLoop(func: Void -> Void) {
backlog.push(func);
if (!isQueued) { OS.queueEvent("endofloop", null); }
}
public static function endOfLoop(func:Void->Void) {
backlog.push(func);
if (!isQueued) {
OS.queueEvent("endofloop", null);
}
}
@:allow(kernel.KernelEvents)
private static function run() {
for (func in backlog) { func(); }
backlog = [];
isQueued = false;
}
@:allow(kernel.KernelEvents)
private static function run() {
for (func in backlog) {
func();
}
backlog = [];
isQueued = false;
}
}

View File

@@ -6,14 +6,14 @@ class Entrypoint {
public static function main() {
try {
Init.initKernel();
}catch(e){
} catch (e) {
Log.error('Error in init: ${e.toString()}');
return;
}
try {
Startup.main();
}catch(e){
} catch (e) {
Log.error('Error in startup: ${e.toString()}');
}
}

View File

@@ -14,11 +14,9 @@ import lib.Debug;
import kernel.ui.WindowManager;
import kernel.peripherals.Peripherals.Peripheral;
import kernel.net.Net;
import kernel.DCEHack; // Important for DCE hack
class Init {
@:allow(kernel.KernelEvents)
private static var mainEvent:MainEvent;
@@ -30,7 +28,7 @@ class Init {
WindowManager.init();
MainTerm.instance = new MainTerm();
if (Turtle.isTurtle()){
if (Turtle.isTurtle()) {
Turtle.instance = new Turtle();
}
@@ -40,7 +38,7 @@ class Init {
GPS.init();
// Register default terminate handler
KernelEvents.onTerminate.handle(_->{
KernelEvents.onTerminate.handle(_ -> {
KernelEvents.shutdown();
});
@@ -50,7 +48,7 @@ class Init {
FS.makeDir("/var/ns");
}
Init.mainEvent = MainLoop.add(()->{
Init.mainEvent = MainLoop.add(() -> {
KernelEvents.startEventLoop();
});

View File

@@ -19,6 +19,7 @@ class KernelEvents {
Depends on: (Nothing)
**/
public static var onAlarm(default, null):Signal<Int>;
public static var onChar(default, null):Signal<String>;
public static var onDisk(default, null):Signal<String>;
public static var onDiskEject(default, null):Signal<String>;
@@ -93,10 +94,10 @@ class KernelEvents {
private static final onWebsocketMessageTrigger:SignalTrigger<{url:String, message:String, isBinary:Bool}> = Signal.trigger();
private static final onWebsocketSuccessTrigger:SignalTrigger<{url:String, handle:Any}> = Signal.trigger();
private static var stopLoop:Bool = false;
private static var stopLoop:Bool = false;
@:allow(kernel.Init)
private static function init() {
private static function init() {
onAlarm = onAlarmTrigger.asSignal();
onChar = onCharTrigger.asSignal();
onDisk = onDiskTrigger.asSignal();
@@ -133,21 +134,20 @@ class KernelEvents {
Start pulling events. Blocking.
**/
@:allow(kernel.Init)
private static function startEventLoop() {
private static function startEventLoop() {
while (!stopLoop) {
var event:Table<Int, Dynamic> = pullEvents();
var eventName:String = event[1];
try {
fireSignal(eventName,event);
}catch(e:Dynamic) {
fireSignal(eventName, event);
} catch (e:Dynamic) {
Log.error('Error while handling event: $eventName: ${e}');
}
}
}
public static function shutdown() {
// clearing screens
for (screen in Peripheral.getAllScreens()) {
screen.reset();
@@ -159,11 +159,11 @@ class KernelEvents {
Init.mainEvent.stop();
}
private static function pullEvents():Table<Int, Dynamic> {
private static function pullEvents():Table<Int, Dynamic> {
return cast TableTools.pack(Coroutine.yield(null));
}
private static function fireSignal(eventName: String,event:Table<Int, Dynamic> ) {
private static function fireSignal(eventName:String, event:Table<Int, Dynamic>) {
switch eventName {
case "alarm":
onAlarmTrigger.trigger(event[2]);
@@ -252,36 +252,66 @@ class KernelEvents {
}
@:allow(lib.Debug)
private static function printListenerCount() {
if (onAlarmTrigger.getLength() > 0) Log.debug("onAlarm: " + onAlarmTrigger.getLength());
if (onCharTrigger.getLength() > 0) Log.debug("onChar: " + onCharTrigger.getLength());
if (onDiskTrigger.getLength() > 0) Log.debug("onDisk: " + onDiskTrigger.getLength());
if (onDiskEjectTrigger.getLength() > 0) Log.debug("onDiskEject: " + onDiskEjectTrigger.getLength());
if (onHttpCheckTrigger.getLength() > 0) Log.debug("onHttpCheck: " + onHttpCheckTrigger.getLength());
if (onHttpFailureTrigger.getLength() > 0) Log.debug("onHttpFailure: " + onHttpFailureTrigger.getLength());
if (onHttpSuccessTrigger.getLength() > 0) Log.debug("onHttpSuccess: " + onHttpSuccessTrigger.getLength());
if (onKeyTrigger.getLength() > 0) Log.debug("onKey: " + onKeyTrigger.getLength());
if (onKeyUpTrigger.getLength() > 0) Log.debug("onKeyUp: " + onKeyUpTrigger.getLength());
if (onModemMessageTrigger.getLength() > 0) Log.debug("onModemMessage: " + onModemMessageTrigger.getLength());
if (onMonitorResizeTrigger.getLength() > 0) Log.debug("onMonitorResize: " + onMonitorResizeTrigger.getLength());
if (onMonitorTouchTrigger.getLength() > 0) Log.debug("onMonitorTouch: " + onMonitorTouchTrigger.getLength());
if (onMouseClickTrigger.getLength() > 0) Log.debug("onMouseClick: " + onMouseClickTrigger.getLength());
if (onMouseDragTrigger.getLength() > 0) Log.debug("onMouseDrag: " + onMouseDragTrigger.getLength());
if (onMouseScrollTrigger.getLength() > 0) Log.debug("onMouseScroll: " + onMouseScrollTrigger.getLength());
if (onMouseUpTrigger.getLength() > 0) Log.debug("onMouseUp: " + onMouseUpTrigger.getLength());
if (onPasteTrigger.getLength() > 0) Log.debug("onPaste: " + onPasteTrigger.getLength());
if (onPeripheralTrigger.getLength() > 0) Log.debug("onPeripheral: " + onPeripheralTrigger.getLength());
if (onPeripheralDetachTrigger.getLength() > 0) Log.debug("onPeripheralDetach: " + onPeripheralDetachTrigger.getLength());
if (onRedstoneTrigger.getLength() > 0) Log.debug("onRedstone: " + onRedstoneTrigger.getLength());
if (onSpeakerAudioEmptyTrigger.getLength() > 0) Log.debug("onSpeakerAudioEmpty: " + onSpeakerAudioEmptyTrigger.getLength());
if (onTaskCompleteTrigger.getLength() > 0) Log.debug("onTaskComplete: " + onTaskCompleteTrigger.getLength());
if (onTermResizeTrigger.getLength() > 0) Log.debug("onTermResize: " + onTermResizeTrigger.getLength());
if (onTerminateTrigger.getLength() > 0) Log.debug("onTerminate: " + onTerminateTrigger.getLength());
if (onTimerTrigger.getLength() > 0) Log.debug("onTimer: " + onTimerTrigger.getLength());
if (onTurtleInventoryTrigger.getLength() > 0) Log.debug("onTurtleInventory: " + onTurtleInventoryTrigger.getLength());
if (onWebsocketCloseTrigger.getLength() > 0) Log.debug("onWebsocketClose: " + onWebsocketCloseTrigger.getLength());
if (onWebsocketFailureTrigger.getLength() > 0) Log.debug("onWebsocketFailure: " + onWebsocketFailureTrigger.getLength());
if (onWebsocketMessageTrigger.getLength() > 0) Log.debug("onWebsocketMessage: " + onWebsocketMessageTrigger.getLength());
if (onWebsocketSuccessTrigger.getLength() > 0) Log.debug("onWebsocketSuccess: " + onWebsocketSuccessTrigger.getLength());
private static function printListenerCount() {
if (onAlarmTrigger.getLength() > 0)
Log.debug("onAlarm: " + onAlarmTrigger.getLength());
if (onCharTrigger.getLength() > 0)
Log.debug("onChar: " + onCharTrigger.getLength());
if (onDiskTrigger.getLength() > 0)
Log.debug("onDisk: " + onDiskTrigger.getLength());
if (onDiskEjectTrigger.getLength() > 0)
Log.debug("onDiskEject: " + onDiskEjectTrigger.getLength());
if (onHttpCheckTrigger.getLength() > 0)
Log.debug("onHttpCheck: " + onHttpCheckTrigger.getLength());
if (onHttpFailureTrigger.getLength() > 0)
Log.debug("onHttpFailure: " + onHttpFailureTrigger.getLength());
if (onHttpSuccessTrigger.getLength() > 0)
Log.debug("onHttpSuccess: " + onHttpSuccessTrigger.getLength());
if (onKeyTrigger.getLength() > 0)
Log.debug("onKey: " + onKeyTrigger.getLength());
if (onKeyUpTrigger.getLength() > 0)
Log.debug("onKeyUp: " + onKeyUpTrigger.getLength());
if (onModemMessageTrigger.getLength() > 0)
Log.debug("onModemMessage: " + onModemMessageTrigger.getLength());
if (onMonitorResizeTrigger.getLength() > 0)
Log.debug("onMonitorResize: " + onMonitorResizeTrigger.getLength());
if (onMonitorTouchTrigger.getLength() > 0)
Log.debug("onMonitorTouch: " + onMonitorTouchTrigger.getLength());
if (onMouseClickTrigger.getLength() > 0)
Log.debug("onMouseClick: " + onMouseClickTrigger.getLength());
if (onMouseDragTrigger.getLength() > 0)
Log.debug("onMouseDrag: " + onMouseDragTrigger.getLength());
if (onMouseScrollTrigger.getLength() > 0)
Log.debug("onMouseScroll: " + onMouseScrollTrigger.getLength());
if (onMouseUpTrigger.getLength() > 0)
Log.debug("onMouseUp: " + onMouseUpTrigger.getLength());
if (onPasteTrigger.getLength() > 0)
Log.debug("onPaste: " + onPasteTrigger.getLength());
if (onPeripheralTrigger.getLength() > 0)
Log.debug("onPeripheral: " + onPeripheralTrigger.getLength());
if (onPeripheralDetachTrigger.getLength() > 0)
Log.debug("onPeripheralDetach: " + onPeripheralDetachTrigger.getLength());
if (onRedstoneTrigger.getLength() > 0)
Log.debug("onRedstone: " + onRedstoneTrigger.getLength());
if (onSpeakerAudioEmptyTrigger.getLength() > 0)
Log.debug("onSpeakerAudioEmpty: " + onSpeakerAudioEmptyTrigger.getLength());
if (onTaskCompleteTrigger.getLength() > 0)
Log.debug("onTaskComplete: " + onTaskCompleteTrigger.getLength());
if (onTermResizeTrigger.getLength() > 0)
Log.debug("onTermResize: " + onTermResizeTrigger.getLength());
if (onTerminateTrigger.getLength() > 0)
Log.debug("onTerminate: " + onTerminateTrigger.getLength());
if (onTimerTrigger.getLength() > 0)
Log.debug("onTimer: " + onTimerTrigger.getLength());
if (onTurtleInventoryTrigger.getLength() > 0)
Log.debug("onTurtleInventory: " + onTurtleInventoryTrigger.getLength());
if (onWebsocketCloseTrigger.getLength() > 0)
Log.debug("onWebsocketClose: " + onWebsocketCloseTrigger.getLength());
if (onWebsocketFailureTrigger.getLength() > 0)
Log.debug("onWebsocketFailure: " + onWebsocketFailureTrigger.getLength());
if (onWebsocketMessageTrigger.getLength() > 0)
Log.debug("onWebsocketMessage: " + onWebsocketMessageTrigger.getLength());
if (onWebsocketSuccessTrigger.getLength() > 0)
Log.debug("onWebsocketSuccess: " + onWebsocketSuccessTrigger.getLength());
}
}

View File

@@ -6,51 +6,53 @@ import lib.KVStore;
import cc.Settings;
class KernelSettings {
private static inline function setAllowStartup(value: Bool) {
Settings.set("shell.allow_startup", value);
}
private static inline function setAllowStartup(value:Bool) {
Settings.set("shell.allow_startup", value);
}
private static inline function setAllowStartupFromFloppy(value: Bool) {
Settings.set("shell.allow_disk_startup", value);
}
private static inline function setAllowStartupFromFloppy(value:Bool) {
Settings.set("shell.allow_disk_startup", value);
}
private static function set(name: String, value: Dynamic) {
var kvstore = new KVStore("kernel");
kvstore.set(name, value);
kvstore.save();
}
private static function set(name:String, value:Dynamic) {
var kvstore = new KVStore("kernel");
kvstore.set(name, value);
kvstore.save();
}
private static function get(name: String): Null<Dynamic> {
var kvstore = new KVStore("kernel");
return kvstore.get(name);
}
private static function get(name:String):Null<Dynamic> {
var kvstore = new KVStore("kernel");
return kvstore.get(name);
}
public static var hostname(get,set): String;
private static var _hostname:String = get("hostname");
private static inline function get_hostname():String {
public static var hostname(get, set):String;
private static var _hostname:String = get("hostname");
private static inline function get_hostname():String {
return _hostname;
}
private static inline function set_hostname(value:String):String {
OS.setComputerLabel(value);
set("hostname", value);
_hostname = value;
return value;
private static inline function set_hostname(value:String):String {
OS.setComputerLabel(value);
set("hostname", value);
_hostname = value;
return value;
}
public static var siteController(get,set): NetworkID;
private static var _siteController:NetworkID = get("siteController");
public static var siteController(get, set):NetworkID;
private static var _siteController:NetworkID = get("siteController");
private static function get_siteController():NetworkID {
return _siteController;
}
private static function set_siteController(value:NetworkID):NetworkID {
if (value == null) {
return get_siteController();
}
if (value == null) {
return get_siteController();
}
set("siteController", value);
_siteController = value;
return value;
set("siteController", value);
_siteController = value;
return value;
}
}

View File

@@ -100,6 +100,6 @@ class MainTerm implements TermWriteable {
this.setBackgroundColor(Black);
this.setTextColor(White);
this.clear();
this.setCursorPos(0,0);
this.setCursorPos(0, 0);
}
}

View File

@@ -3,10 +3,10 @@ package kernel.binstore;
import kernel.ps.Process;
/**
Represents a callable program.
Represents a callable program.
**/
typedef Bin = {
c: Class<Process>,
name: String,
aliases: Array<String>,
c:Class<Process>,
name:String,
aliases:Array<String>,
}

View File

@@ -22,53 +22,53 @@ import bin.Disk;
import haxe.ds.ReadOnlyArray;
class BinStore {
private static final store:ReadOnlyArray<Bin> = [
{c: Disk, name: "Disk", aliases: ["disk"]},
{c: GPS, name: "GPS", aliases: ["gps"]},
{c: HelloWorld, name: "HelloWorld", aliases: ["hello"]},
{c: KernelLog, name: "KernelLog", aliases: ["log"]},
{c: Net, name: "Net", aliases: ["net"]},
{c: Redstone, name: "Redstone", aliases: ["redstone","rs"]},
{c: Terminal, name: "Terminal", aliases: ["terminal","term"]},
{c: Turtle, name: "Turtle", aliases: ["turtle"]},
{c: LSPS, name: "PM", aliases: ["lsps"]},
{c: Service, name: "Service", aliases: ["service","srv"]},
{c: HelloWorldService, name: "HelloWorldService", aliases: ["hello-service"] },
{c: SiteRessourceController, name: "SiteRessourceController", aliases: ["srsc"]},
{c: CLI, name: "SRSC CLI", aliases: ["srsc-cli"]},
{c: Perf, name: "Perf", aliases: ["perf"]},
{c: KSettings, name: "KSettings", aliases: ["ksettings","ks"]},
{c: ResManager, name: "ResManager", aliases: ["resmanager","resmgr"]},
{c: Res, name: "Res", aliases: ["res"]},
{c: ID , name: "ID", aliases: ["id"]},
{c: PFClient, name: "PFClient", aliases: ["pfclient"]}
];
private static final store:ReadOnlyArray<Bin> = [
{c: Disk, name: "Disk", aliases: ["disk"]},
{c: GPS, name: "GPS", aliases: ["gps"]},
{c: HelloWorld, name: "HelloWorld", aliases: ["hello"]},
{c: KernelLog, name: "KernelLog", aliases: ["log"]},
{c: Net, name: "Net", aliases: ["net"]},
{c: Redstone, name: "Redstone", aliases: ["redstone", "rs"]},
{c: Terminal, name: "Terminal", aliases: ["terminal", "term"]},
{c: Turtle, name: "Turtle", aliases: ["turtle"]},
{c: LSPS, name: "PM", aliases: ["lsps"]},
{c: Service, name: "Service", aliases: ["service", "srv"]},
{c: HelloWorldService, name: "HelloWorldService", aliases: ["hello-service"]},
{c: SiteRessourceController, name: "SiteRessourceController", aliases: ["srsc"]},
{c: CLI, name: "SRSC CLI", aliases: ["srsc-cli"]},
{c: Perf, name: "Perf", aliases: ["perf"]},
{c: KSettings, name: "KSettings", aliases: ["ksettings", "ks"]},
{c: ResManager, name: "ResManager", aliases: ["resmanager", "resmgr"]},
{c: Res, name: "Res", aliases: ["res"]},
{c: ID, name: "ID", aliases: ["id"]},
{c: PFClient, name: "PFClient", aliases: ["pfclient"]}
];
public static function getBinByName(name:String):Null<Bin> {
for (bin in store) {
if (bin.name == name) {
return bin;
}
}
return null;
}
public static function getBinByName(name:String):Null<Bin> {
for (bin in store) {
if (bin.name == name) {
return bin;
}
}
return null;
}
public static function getBinByAlias(alias:String):Null<Bin> {
for (bin in store) {
for (a in bin.aliases) {
if (a == alias) {
return bin;
}
}
}
return null;
}
public static function getBinByAlias(alias:String):Null<Bin> {
for (bin in store) {
for (a in bin.aliases) {
if (a == alias) {
return bin;
}
}
}
return null;
}
public static function getNameByAlias(alias: String): String {
var bin = getBinByAlias(alias);
if (bin == null) {
return null;
}
return bin.name;
}
public static function getNameByAlias(alias:String):String {
var bin = getBinByAlias(alias);
if (bin == null) {
return null;
}
return bin.name;
}
}

View File

@@ -13,79 +13,79 @@ using lua.Table;
Wrapper to interact with the filesystem.
**/
class FS {
public static inline function list(path: String):ReadOnlyArray<String> {
public static inline function list(path:String):ReadOnlyArray<String> {
return FileSystem.list(path).toArray();
}
public static inline function combine(base: String, part: String): String {
return FileSystem.combine(base,part);
public static inline function combine(base:String, part:String):String {
return FileSystem.combine(base, part);
}
public static inline function getName(path: String): String {
public static inline function getName(path:String):String {
return FileSystem.getName(path);
}
public static inline function getDir(path: String): String {
public static inline function getDir(path:String):String {
return FileSystem.getDir(path);
}
public static inline function getSize(path: String):Int {
public static inline function getSize(path:String):Int {
return FileSystem.getSize(path);
}
public static inline function exists(path: String):Bool {
public static inline function exists(path:String):Bool {
return FileSystem.exists(path);
}
public static inline function isDir(path: String): Bool {
public static inline function isDir(path:String):Bool {
return FileSystem.isDir(path);
}
public static inline function isReadOnly(path: String):Bool {
public static inline function isReadOnly(path:String):Bool {
return FileSystem.isReadOnly(path);
}
public static inline function makeDir(path: String):Void {
public static inline function makeDir(path:String):Void {
FileSystem.makeDir(path);
}
public static inline function move(src:String,dest:String):Void {
FileSystem.move(src,dest);
public static inline function move(src:String, dest:String):Void {
FileSystem.move(src, dest);
}
public static inline function copy(src:String,dest:String):Void {
FileSystem.copy(src,dest);
public static inline function copy(src:String, dest:String):Void {
FileSystem.copy(src, dest);
}
public static inline function delete(path: String):Void {
public static inline function delete(path:String):Void {
FileSystem.delete(path);
}
public static inline function openRead(path:String): ReadHandle{
return FileSystem.open(path,Read);
public static inline function openRead(path:String):ReadHandle {
return FileSystem.open(path, Read);
}
public static inline function openWrite(path: String): WriteHandle {
return FileSystem.open(path,Write);
public static inline function openWrite(path:String):WriteHandle {
return FileSystem.open(path, Write);
}
public static inline function openAppend(path: String): WriteHandle {
return FileSystem.open(path,Append);
public static inline function openAppend(path:String):WriteHandle {
return FileSystem.open(path, Append);
}
public static inline function openReadBinary(path:String): ReadBinaryHandle {
return FileSystem.open(path,BinaryRead);
public static inline function openReadBinary(path:String):ReadBinaryHandle {
return FileSystem.open(path, BinaryRead);
}
public static inline function openWriteBinary(path: String): WriteBinaryHandle {
return FileSystem.open(path,BinaryWrite);
public static inline function openWriteBinary(path:String):WriteBinaryHandle {
return FileSystem.open(path, BinaryWrite);
}
public static inline function openAppendBinary(path: String): WriteBinaryHandle {
return FileSystem.open(path,BinaryAppend);
public static inline function openAppendBinary(path:String):WriteBinaryHandle {
return FileSystem.open(path, BinaryAppend);
}
public static inline function find(pattern: String):ReadOnlyArray<String> {
public static inline function find(pattern:String):ReadOnlyArray<String> {
return FileSystem.find(pattern).toArray();
}
@@ -97,7 +97,7 @@ class FS {
return FileSystem.getCapacity(path);
}
public static inline function attributes(path: String):FileAttributes {
public static inline function attributes(path:String):FileAttributes {
return FileSystem.attributes(path);
}
}

View File

@@ -5,107 +5,103 @@ import cc.FileSystem.FileHandle;
using tink.CoreApi;
abstract ReadHandle(FileHandle) from FileHandle {
public inline function new(handle:FileHandle) {
this = handle;
}
public inline function readLine(?withTrailing:Bool = false):Null<String>{
public inline function readLine(?withTrailing:Bool = false):Null<String> {
return this.readLine(withTrailing);
}
public inline function readAll():Null<String>{
public inline function readAll():Null<String> {
return this.readAll();
}
public inline function read(?count:Int = 1):Null<String>{
public inline function read(?count:Int = 1):Null<String> {
return this.read(count);
}
public inline function close():Void{
public inline function close():Void {
this.close();
}
}
abstract WriteHandle(FileHandle) from FileHandle {
public inline function new(handle:FileHandle) {
this = handle;
}
public inline function write(data:String):Void{
public inline function write(data:String):Void {
this.write(data);
}
public inline function writeLine(data:String):Void{
public inline function writeLine(data:String):Void {
this.writeLine(data);
}
public inline function flush():Void{
public inline function flush():Void {
this.flush();
}
public inline function close():Void{
public inline function close():Void {
this.close();
}
}
abstract ReadBinaryHandle(FileHandle) from FileHandle {
public inline function new(handle:FileHandle) {
this = handle;
}
public inline function readLine(?withTrailing:Bool = false):Null<String>{
public inline function readLine(?withTrailing:Bool = false):Null<String> {
return this.readLine(withTrailing);
}
public inline function readAll():Null<String>{
public inline function readAll():Null<String> {
return this.readAll();
}
public inline function read(count:Int):Null<String>{
public inline function read(count:Int):Null<String> {
return this.read(count);
}
public inline function readByte():Null<Int>{
public inline function readByte():Null<Int> {
return this.read();
}
public inline function seek(?whence:BinarySeekWhence = Current, ?offset:Int):Void{
this.seek(whence,offset);
public inline function seek(?whence:BinarySeekWhence = Current, ?offset:Int):Void {
this.seek(whence, offset);
}
public inline function close():Void{
public inline function close():Void {
this.close();
}
}
abstract WriteBinaryHandle(FileHandle) from FileHandle {
public inline function new(handle:FileHandle) {
this = handle;
}
public inline function write(data: String):Void{
public inline function write(data:String):Void {
this.write(data);
}
// TODO
public inline function writeByte(data: Int):Void{
public inline function writeByte(data:Int):Void {
// this.write(data);
}
public inline function flush():Void{
public inline function flush():Void {
this.flush();
}
public inline function close():Void{
public inline function close():Void {
this.close();
}
public inline function seek(?whence:BinarySeekWhence = Current, ?offset:Int):Void{
this.seek(whence,offset);
public inline function seek(?whence:BinarySeekWhence = Current, ?offset:Int):Void {
this.seek(whence, offset);
}
}

View File

@@ -19,9 +19,9 @@ class GPS {
private static var shouldDoWholeNumberCheck = true;
private static var posAccuracy = 0; // 0 = unkown, 1 = (ins,best guess), 2 = (stored/manual,should be right), 3 = (gps,confirmed)
private static var cachedPosition:Pos3;
private static var lastPositionResponse: Array<{pos:Pos3,dist:Float}> = [];
private static var lastPositionResponse:Array<{pos:Pos3, dist:Float}> = [];
private static var futureResolve: (pos:Null<Pos3>) -> Void = null;
private static var futureResolve:(pos:Null<Pos3>) -> Void = null;
@:allow(kernel.Init)
private static function init() {
@@ -30,7 +30,7 @@ class GPS {
public static function setManualPosition(pos:Pos3) {
var kvstore = new KVStore("gps");
kvstore.set("mpos",pos);
kvstore.set("mpos", pos);
kvstore.save();
if (cachedPosition == null) {
@@ -61,7 +61,7 @@ class GPS {
public static function locate():Future<Null<Pos3>> {
// TODO: implenet a timeout
// TODO: dont send a request twice if the last one is still pending or we moved
return new Future<Null<Pos3>>((resolve)->{
return new Future<Null<Pos3>>((resolve) -> {
futureResolve = resolve;
sendPositionRequest();
return null;
@@ -73,10 +73,11 @@ class GPS {
}
private static function persistCachedPositon() {
if (cachedPosition == null) return;
if (cachedPosition == null)
return;
var kvstore = new KVStore("gps");
kvstore.set("cpos",cachedPosition);
kvstore.set("cpos", cachedPosition);
kvstore.save();
}
@@ -94,7 +95,7 @@ class GPS {
return;
}
if (mPos != null && cPos != null && mPos != cPos){
if (mPos != null && cPos != null && mPos != cPos) {
// Both are different, so we can use the manual position
cachedPosition = mPos;
posAccuracy = 1;
@@ -114,7 +115,6 @@ class GPS {
posAccuracy = 2;
return;
}
}
private static function sendPositionRequest() {
@@ -122,33 +122,39 @@ class GPS {
}
@:allow(kernel.net.Net)
private static function handlePackage(pack:Package<Noise>, dist: Float,iface: INetworkInterface) {
private static function handlePackage(pack:Package<Noise>, dist:Float, iface:INetworkInterface) {
switch (pack.type) {
case GPSRequest:
if (!shouldRespond) return;
if (posAccuracy < 2) return;
if (cachedPosition == null) return;
if (!shouldRespond)
return;
if (posAccuracy < 2)
return;
if (cachedPosition == null)
return;
var response = new Package(Net.networkID,pack.fromID, pack.msgID, GPSResponse(cachedPosition),null,0);
iface.send(pack.fromID,Net.networkID,response);
var response = new Package(Net.networkID, pack.fromID, pack.msgID, GPSResponse(cachedPosition), null, 0);
iface.send(pack.fromID, Net.networkID, response);
case GPSResponse(pos):
if (lastPositionResponse.contains({pos:pos,dist:dist})) return; // Ignore duplicate responses
if (lastPositionResponse.contains({pos: pos, dist: dist}))
return; // Ignore duplicate responses
lastPositionResponse.push({pos:pos,dist:dist});
lastPositionResponse.push({pos: pos, dist: dist});
// TODO: wait for a few seconds before calculating the position, so we can get more responses
if (lastPositionResponse.length < 4) return; // We need at least 3 responses to calculate the position
if (lastPositionResponse.length < 4)
return; // We need at least 3 responses to calculate the position
var calculatedPosition = calculatePosition();
if (calculatedPosition != null){
if (calculatedPosition != null) {
calculatedPosition = calculatedPosition.round();
}
lastPositionResponse = []; // Reset the response array
if (calculatedPosition == null) return;
if (calculatedPosition == null)
return;
cachedPosition = calculatedPosition;
posAccuracy = 3;
@@ -158,7 +164,8 @@ class GPS {
}
private static function calculatePosition():Null<Pos3> {
if (lastPositionResponse.length < 3) return null;
if (lastPositionResponse.length < 3)
return null;
// do a simple trilateration with the last 3 responses for now
var p1 = lastPositionResponse[0].pos;
@@ -169,13 +176,14 @@ class GPS {
var r2 = lastPositionResponse[1].dist;
var r3 = lastPositionResponse[2].dist;
var result = trilateration(p1,p2,p3,r1,r2,r3);
var result = trilateration(p1, p2, p3, r1, r2, r3);
if (result.a.close(result.b)) return result.a;
if (result.a.close(result.b))
return result.a;
// If we have more than 3 responses, we can use the 4th response to determine which of the two positions is correct
// TODO: if this is a pocket computer we cant use this since it can move freely
if (lastPositionResponse.length > 3){
if (lastPositionResponse.length > 3) {
var err1 = Math.abs(result.a.distance(lastPositionResponse[3].pos) - lastPositionResponse[3].dist);
var err2 = Math.abs(result.b.distance(lastPositionResponse[3].pos) - lastPositionResponse[3].dist);
@@ -184,12 +192,15 @@ class GPS {
return null; // The two positions are essentially the same, so we cant determine which one is correct
}
if (err1 < err2) return result.a;
if (err2 < err1) return result.b;
if (err1 < err2)
return result.a;
if (err2 < err1)
return result.b;
}
// last resort, just use the position that is closest to a whole number (whithin a resonable margin of error)
if (!shouldDoWholeNumberCheck) return null;
if (!shouldDoWholeNumberCheck)
return null;
// TODO: mark the position as not so accurate if we use this method
@@ -208,7 +219,7 @@ class GPS {
/**
Determines the position(s) of a point given 3 other points and the distance to each of them.
**/
private static function trilateration(p1:Pos3,p2:Pos3,p3: Pos3,r1:Float,r2:Float,r3:Float):Pair<Pos3,Pos3> {
private static function trilateration(p1:Pos3, p2:Pos3, p3:Pos3, r1:Float, r2:Float, r3:Float):Pair<Pos3, Pos3> {
var a2b = p2 - p1;
var a2c = p3 - p1;
@@ -227,9 +238,9 @@ class GPS {
var zSquared = r1 * r1 - x * x - y * y;
if (zSquared > 0) {
var z = Math.sqrt(zSquared);
return new Pair(result + (ez * z),result - (ez * z));
return new Pair(result + (ez * z), result - (ez * z));
}
return new Pair(result,result);
return new Pair(result, result);
}
}

View File

@@ -7,8 +7,8 @@ import lib.Pos3;
using tink.CoreApi;
class INS {
private static var heading: Null<Pos3> = null;
private static var alingment: Int = 1; // 0 = degraded, 1 = not aligned, 2 = aligned
private static var heading:Null<Pos3> = null;
private static var alingment:Int = 1; // 0 = degraded, 1 = not aligned, 2 = aligned
@:allow(kernel.turtle.Turtle)
private static function moveForward() {
@@ -40,7 +40,8 @@ class INS {
@:allow(kernel.turtle.Turtle)
private static function turnLeft() {
if (heading == null) return;
if (heading == null)
return;
if (heading.x == 0 && heading.z == -1) {
heading = {x: -1, y: 0, z: 0};
} else if (heading.x == -1 && heading.z == 0) {
@@ -54,7 +55,8 @@ class INS {
@:allow(kernel.turtle.Turtle)
private static function turnRight() {
if (heading == null) return;
if (heading == null)
return;
if (heading.x == 0 && heading.z == -1) {
heading = {x: 1, y: 0, z: 0};
} else if (heading.x == -1 && heading.z == 0) {
@@ -66,7 +68,7 @@ class INS {
}
}
private static function move(dir: Null<Pos3>) {
private static function move(dir:Null<Pos3>) {
Log.debug('INS move: $dir');
var pos = GPS.getPosition();
var newPos = pos + dir;
@@ -77,17 +79,16 @@ class INS {
return heading;
}
public static function align(): Promise<Noise> {
public static function align():Promise<Noise> {
Log.info("Aligning INS");
return new Promise<Noise>((resolve,reject)->{
if (Turtle.instance.getFuelLevel() < 2){
return new Promise<Noise>((resolve, reject) -> {
if (Turtle.instance.getFuelLevel() < 2) {
Log.warn("Not enough fuel to align");
reject(new Error("Not enough fuel to align"));
return null;
}
GPS.locate().handle((pos1)->{
GPS.locate().handle((pos1) -> {
Log.debug('pos1: $pos1');
if (pos1 == null) {
Log.warn("GPS not available for 1st position");
@@ -103,7 +104,7 @@ class INS {
return;
}
GPS.locate().handle((pos2)->{
GPS.locate().handle((pos2) -> {
Log.debug('pos2: $pos2');
if (pos2 == null) {
Log.warn("GPS not available for 2nd position");
@@ -111,7 +112,7 @@ class INS {
return;
}
var cHeading = calcHeading(pos1,pos2,moved);
var cHeading = calcHeading(pos1, pos2, moved);
if (cHeading == null) {
Log.error("Can't calculate heading");
reject(new Error("Can't calculate heading"));
@@ -124,7 +125,6 @@ class INS {
resolve(Noise);
});
});
return null;
});
@@ -138,7 +138,7 @@ class INS {
return 1;
} else {
Turtle.instance.turnLeft(); // TODO: Check if successfull
if (Turtle.instance.forward().isSuccess()){
if (Turtle.instance.forward().isSuccess()) {
return 2;
} else if (Turtle.instance.back().isSuccess()) {
return 3;
@@ -149,7 +149,7 @@ class INS {
}
}
private static function calcHeading(pos1: Pos3,pos2:Pos3,moved:Int): Null<Pos3> {
private static function calcHeading(pos1:Pos3, pos2:Pos3, moved:Int):Null<Pos3> {
if (moved == 0) {
return pos1 - pos2;
} else if (moved == 1) {
@@ -200,5 +200,4 @@ class INS {
private static function rotatePos3ToLeft(pos3:Pos3):Pos3 {
return rotatePos3ToRight(rotatePos3ToRight(rotatePos3ToRight(pos3)));
}
}

View File

@@ -3,16 +3,15 @@ package kernel.http;
using lua.Table;
class HTTPFailure {
public final reason:String;
public final statusCode:Null<StatusCode>;
public final headers:Map<String,String>;
public final headers:Map<String, String>;
public final body:String;
@:allow(kernel.http)
private function new(failReason: String, ?handle: cc.HTTP.HTTPResponse) {
private function new(failReason:String, ?handle:cc.HTTP.HTTPResponse) {
this.reason = failReason;
if (handle != null){
if (handle != null) {
this.statusCode = handle.getResponseCode();
this.headers = handle.getResponseHeaders().toMap();
this.body = handle.readAll();

View File

@@ -6,21 +6,21 @@ using tink.CoreApi;
Wrapper for the native HTTP request function.
**/
class Http {
public static function request(url:String,?body:String,?options: String):Future<Outcome<HTTPResponse,HTTPFailure>> {
return new Future<Outcome<HTTPResponse,HTTPFailure>>((resolve) -> {
KernelEvents.onHttpFailure.handle((params)->{
if (params.url == url){
resolve(Failure(new HTTPFailure(params.failReason,params.handle)));
public static function request(url:String, ?body:String, ?options:String):Future<Outcome<HTTPResponse, HTTPFailure>> {
return new Future<Outcome<HTTPResponse, HTTPFailure>>((resolve) -> {
KernelEvents.onHttpFailure.handle((params) -> {
if (params.url == url) {
resolve(Failure(new HTTPFailure(params.failReason, params.handle)));
}
});
KernelEvents.onHttpSuccess.handle((params) -> {
if (params.url == url){
if (params.url == url) {
resolve(Success(new HTTPResponse(params.handle)));
}
});
cc.HTTP.request(url,body);
cc.HTTP.request(url, body);
return null;
});

View File

@@ -3,13 +3,12 @@ package kernel.http;
using lua.Table;
class HTTPResponse {
public final statusCode:StatusCode;
public final headers:Map<String,String>;
public final headers:Map<String, String>;
public final body:String;
@:allow(kernel.http)
private function new(handle: cc.HTTP.HTTPResponse) {
private function new(handle:cc.HTTP.HTTPResponse) {
this.statusCode = handle.getResponseCode();
this.headers = handle.getResponseHeaders().toMap();
this.body = handle.readAll();

View File

@@ -24,28 +24,28 @@ class Log {
}
public static function info(msg:Dynamic, ?pos:haxe.PosInfos) {
log({level: Info, message: Std.string(msg),time: 0},pos);
log({level: Info, message: Std.string(msg), time: 0}, pos);
}
public static function warn(msg:Dynamic, ?pos:haxe.PosInfos) {
log({level: Warn, message: Std.string(msg),time: 0},pos);
log({level: Warn, message: Std.string(msg), time: 0}, pos);
}
public static function error(msg:Dynamic, ?pos:haxe.PosInfos) {
log({level: Error, message: Std.string(msg),time: 0},pos);
log({level: Error, message: Std.string(msg), time: 0}, pos);
}
public static function debug(msg:Dynamic, ?pos:haxe.PosInfos) {
#if debug
log({level: Debug, message: Std.string(msg),time: 0},pos);
log({level: Debug, message: Std.string(msg), time: 0}, pos);
#end
}
public static function silly(msg:Dynamic, ?pos:haxe.PosInfos) {
log({level: Silly, message: Std.string(msg),time: 0},pos);
log({level: Silly, message: Std.string(msg), time: 0}, pos);
}
private static function log(line: LogLine, ?pos:haxe.PosInfos) {
private static function log(line:LogLine, ?pos:haxe.PosInfos) {
line.origin = pos.className;
logLines.push(line);

View File

@@ -1,8 +1,8 @@
package kernel.log;
typedef LogLine = {
level: LogLevel,
message: String,
time: Int,
?origin: String,
level:LogLevel,
message:String,
time:Int,
?origin:String,
}

View File

@@ -1,18 +1,19 @@
package kernel.net;
import kernel.net.Package.GenericPackage;
using tink.CoreApi;
/**
A object that is able to send and receive messages.
**/
interface INetworkInterface {
public function listen(chan: Int):Void;
public function close(chan: Int):Void;
public function isListening(chan: Int): Bool;
public function closeAll(): Void;
public function send(chan: Int,replyChan: Int,payload: Any):Void;
public function listen(chan:Int):Void;
public function close(chan:Int):Void;
public function isListening(chan:Int):Bool;
public function closeAll():Void;
public function send(chan:Int, replyChan:Int, payload:Any):Void;
public function name():String;
public function getBaseRoutingCost():Int;
public var onMessage (default, null): Signal<{pack:GenericPackage,?dist:Float}>;
public var onMessage(default, null):Signal<{pack:GenericPackage, ?dist:Float}>;
}

View File

@@ -2,6 +2,7 @@ package kernel.net;
import kernel.net.Package.GenericPackage;
import kernel.log.Log;
using tink.CoreApi;
/**
@@ -10,17 +11,17 @@ using tink.CoreApi;
class Loopback implements INetworkInterface {
public static final instance:Loopback = new Loopback();
public var onMessage(default, null):Signal<{pack:GenericPackage,dist:Null<Float>}>;
public var onMessage(default, null):Signal<{pack:GenericPackage, dist:Null<Float>}>;
private final onMessageTrigger: SignalTrigger<{pack:GenericPackage,dist:Null<Float>}> = Signal.trigger();
private var openChans: Array<Int> = [];
private final onMessageTrigger:SignalTrigger<{pack:GenericPackage, dist:Null<Float>}> = Signal.trigger();
private var openChans:Array<Int> = [];
private function new() {
this.onMessage = onMessageTrigger.asSignal();
}
public function listen(chan:Int) {
if (!this.openChans.contains(chan)){
if (!this.openChans.contains(chan)) {
this.openChans.push(chan);
}
}
@@ -38,9 +39,9 @@ class Loopback implements INetworkInterface {
}
public function send(chan:Int, replyChan:Int, payload:Any) {
if (this.openChans.contains(chan)){
this.onMessageTrigger.trigger({pack:payload,dist:null});
}else{
if (this.openChans.contains(chan)) {
this.onMessageTrigger.trigger({pack: payload, dist: null});
} else {
Log.silly("Loopback got package on non open channel");
}
}

View File

@@ -21,20 +21,21 @@ class Net {
Depends on: KernelEvents
**/
public static inline final BRODCAST_PORT:Int = 65533;
public static inline final MESSAGE_TIMEOUT:Int = 3;
public static inline final DEFAULT_TTL:Int = 10;
public static final networkID:NetworkID = OS.getComputerID();
private static final responseBus:Map<Int, Callback<Outcome<GenericPackage,Error>>> = new Map();
private static final responseBus:Map<Int, Callback<Outcome<GenericPackage, Error>>> = new Map();
private static final protoHandlers:Map<String, Callback<GenericPackage>> = new Map();
private static var interfaces:Array<INetworkInterface>;
@:allow(kernel.Init)
private static function init() {
interfaces = [for (e in Peripheral.getAllModems()) e ]; // TODO: is this the way to do it?
interfaces = [for (e in Peripheral.getAllModems()) e]; // TODO: is this the way to do it?
interfaces.push(Loopback.instance);
for (interf in interfaces){
for (interf in interfaces) {
setupInterf(interf);
}
@@ -61,8 +62,8 @@ class Net {
});
}
private static function setupInterf(interf: INetworkInterface) {
interf.onMessage.handle(e -> handle(e.pack,interf,e.dist));
private static function setupInterf(interf:INetworkInterface) {
interf.onMessage.handle(e -> handle(e.pack, interf, e.dist));
interf.listen(networkID);
interf.listen(BRODCAST_PORT);
}
@@ -70,8 +71,8 @@ class Net {
/**
Called when a new package comes in.
**/
private static function handle(pack:GenericPackage,interf: INetworkInterface, ?dist: Float) {
if (pack.toID == networkID || pack.toID == Net.BRODCAST_PORT){
private static function handle(pack:GenericPackage, interf:INetworkInterface, ?dist:Float) {
if (pack.toID == networkID || pack.toID == Net.BRODCAST_PORT) {
switch pack.type {
case Data(_) | DataNoResponse(_):
// Let a local proccess handle it
@@ -83,16 +84,16 @@ class Net {
}
case RouteDiscover(_) | RouteDiscoverResponse(_) | RouteDiscoverUpdate(_):
// Delegate to Routing
Routing.handleRoutePackage(cast pack,interf);
Routing.handleRoutePackage(cast pack, interf);
case GPSRequest | GPSResponse(_):
if (dist == null) {
Log.silly("Got a GPS package but no distance was provided");
return;
}
// Delegate to GPS
GPS.handlePackage(cast pack,dist,interf);
GPS.handlePackage(cast pack, dist, interf);
}
}else{
} else {
// New message received but its not ment for us. Forward if possible.
forwardPackage(pack);
}
@@ -118,13 +119,12 @@ class Net {
sendRaw(pack);
}
private static function forwardPackage(pack: GenericPackage) {
if (pack.ttl == 0){
private static function forwardPackage(pack:GenericPackage) {
if (pack.ttl == 0) {
if (pack.type.match(Data(_))) {
// If the package is a data package and the ttl hits 0
// we send a "died" message to the sender
sendAndForget(pack.fromID, "icmp", {type:"died", msgID: pack.msgID});
sendAndForget(pack.fromID, "icmp", {type: "died", msgID: pack.msgID});
}
// Drop package
@@ -133,7 +133,7 @@ class Net {
pack.ttl--;
if (!sendRaw(pack)){
if (!sendRaw(pack)) {
// Cant forward
}
}
@@ -174,13 +174,13 @@ class Net {
Just send the package to the right modem.
Returns true if message was send
**/
private static function sendRaw(pack:GenericPackage): Bool {
private static function sendRaw(pack:GenericPackage):Bool {
var route = Routing.getRouteToID(pack.toID);
if (route == null){
if (route == null) {
return false;
}
route.interf.send(route.rep,networkID,pack);
route.interf.send(route.rep, networkID, pack);
return true;
}
@@ -200,8 +200,7 @@ class Net {
var timeout:Timer = null;
responseBus[pack.msgID] = ((reponse:Outcome<GenericPackage,Error>) -> {
responseBus[pack.msgID] = ((reponse:Outcome<GenericPackage, Error>) -> {
switch reponse {
case Success(pack):
resolve(pack);
@@ -217,10 +216,10 @@ class Net {
timeout = new Timer(MESSAGE_TIMEOUT, () -> {
responseBus.remove(pack.msgID);
reject(new Error(InternalError,"Message timeout"));
reject(new Error(InternalError, "Message timeout"));
});
if (!sendRaw(pack)){
if (!sendRaw(pack)) {
reject(new Error("ID unreachable"));
}
@@ -246,9 +245,9 @@ class Net {
/**
Sends a ping package to the given id. Returns true if there was a response.
**/
public static function ping(toID: NetworkID): Promise<Noise> {
return new Promise<Noise>((resolve,reject)->{
sendAndAwait(toID,"icmp",{type:"ping"}).handle(pack -> {
public static function ping(toID:NetworkID):Promise<Noise> {
return new Promise<Noise>((resolve, reject) -> {
sendAndAwait(toID, "icmp", {type: "ping"}).handle(pack -> {
switch pack {
case Success(_):
resolve(Noise);
@@ -260,7 +259,7 @@ class Net {
});
}
public static function getActiveProtocols(): ReadOnlyArray<String> {
public static function getActiveProtocols():ReadOnlyArray<String> {
var arr = new Array<String>();
for (proto in protoHandlers.keys()) {
@@ -272,7 +271,7 @@ class Net {
@:allow(kernel.gps.GPS)
private static function brodcastGPSRequest() {
var pack: Package<Noise> = {
var pack:Package<Noise> = {
fromID: networkID,
toID: Net.BRODCAST_PORT,
ttl: 0, // Prevent forwarding
@@ -282,7 +281,8 @@ class Net {
};
for (modem in Peripheral.getAllModems()) {
if (!modem.isWireless()) continue;
if (!modem.isWireless())
continue;
modem.send(Net.BRODCAST_PORT, networkID, pack);
}
}

View File

@@ -3,15 +3,15 @@ package kernel.net;
import lib.Pos3;
typedef NetworkID = Int;
typedef GenericPackage = Package<Dynamic> ;
typedef GenericPackage = Package<Dynamic>;
enum PackageTypes {
Data(proto:String);
DataNoResponse(proto:String);
Response;
RouteDiscover(reachableIDs: Array<{id:NetworkID,cost:Int}>);
RouteDiscoverResponse(reachableIDs: Array<{id:NetworkID,cost:Int}>);
RouteDiscoverUpdate(reachableIDs: Array<{id:NetworkID,cost:Int}>);
RouteDiscover(reachableIDs:Array<{id:NetworkID, cost:Int}>);
RouteDiscoverResponse(reachableIDs:Array<{id:NetworkID, cost:Int}>);
RouteDiscoverUpdate(reachableIDs:Array<{id:NetworkID, cost:Int}>);
GPSResponse(pos:Pos3);
GPSRequest();
}
@@ -25,7 +25,7 @@ enum PackageTypes {
public final msgID:Int;
public final type:PackageTypes;
public final data:T;
public var ttl: Int;
public var ttl:Int;
public function new(fromID:NetworkID, toID:NetworkID, msgID:Int, type:PackageTypes, data:T, ttl:Int) {
this.fromID = fromID;

View File

@@ -20,7 +20,6 @@ class Routing {
/**
Depends on: Peripheral
**/
public static inline final UPDATE_WAIT_TIME:Float = 1;
public static var onNewNeigbor(default, null):Signal<Int>;

View File

@@ -168,8 +168,7 @@ class BigReactor implements IPeripheral {
// getFuelStats
// getEnergyStats
// getCoolantFluidStats
// getHotFluidStats
// getHotFluidStats
// TODO: need research
// isMethodAvailable(method: String): Bool
// mbGetMaximumCoordinate(): Pos3

View File

@@ -4,47 +4,47 @@ import cc.Peripheral;
import kernel.net.Package.NetworkID;
class Computer implements IPeripheral {
public static inline final TYPE_NAME:String = "computer";
public static inline final TYPE_NAME:String = "computer";
private final addr:String;
private final addr:String;
@:allow(kernel.peripherals)
private function new(addr: String) {
@:allow(kernel.peripherals)
private function new(addr:String) {
this.addr = addr;
}
}
public function getAddr():String {
return addr;
}
public function getType():String {
public function getType():String {
return Computer.TYPE_NAME;
}
public function isOn():Bool {
return Peripheral.call(addr, "isOn");
}
public function isOn():Bool {
return Peripheral.call(addr, "isOn");
}
public function getLabel():Null<String> {
return Peripheral.call(addr, "getLabel");
}
public function getLabel():Null<String> {
return Peripheral.call(addr, "getLabel");
}
/**
Return -1 if no ID set yet
**/
public function getID():NetworkID{
return Peripheral.call(addr, "getID");
}
/**
Return -1 if no ID set yet
**/
public function getID():NetworkID {
return Peripheral.call(addr, "getID");
}
public function reboot() {
Peripheral.call(addr, "reboot");
}
public function reboot() {
Peripheral.call(addr, "reboot");
}
public function shutdown() {
Peripheral.call(addr, "shutdown");
}
public function shutdown() {
Peripheral.call(addr, "shutdown");
}
public function turnOn() {
Peripheral.call(addr, "turnOn");
}
public function turnOn() {
Peripheral.call(addr, "turnOn");
}
}

View File

@@ -1,6 +1,7 @@
package kernel.peripherals;
import cc.Peripheral;
using tink.CoreApi;
class Drive implements IPeripheral {
@@ -15,21 +16,21 @@ class Drive implements IPeripheral {
private final onDiskEjectTrigger:SignalTrigger<Noise> = Signal.trigger();
@:allow(kernel.peripherals)
private function new(addr: String) {
private function new(addr:String) {
this.addr = addr;
this.native = Peripheral.wrap(addr);
this.onDiskInsert = this.onDiskInsertTrigger.asSignal();
this.onDiskEject = this.onDiskEjectTrigger.asSignal();
KernelEvents.onDisk.handle((addr) ->{
if (addr == this.addr){
KernelEvents.onDisk.handle((addr) -> {
if (addr == this.addr) {
this.onDiskInsertTrigger.trigger(null);
}
});
KernelEvents.onDiskEject.handle((addr)->{
if (addr == this.addr){
KernelEvents.onDiskEject.handle((addr) -> {
if (addr == this.addr) {
this.onDiskEjectTrigger.trigger(null);
}
});
@@ -43,14 +44,14 @@ class Drive implements IPeripheral {
return TYPE_NAME;
}
public inline function isDiskPresent(): Bool {
public inline function isDiskPresent():Bool {
return this.native.isDiskPresent();
}
/**
The label of the disk, or `null` if either no disk is inserted or the disk doesn't have a label.
**/
public inline function getDiskLabel(): Null<String> {
public inline function getDiskLabel():Null<String> {
return this.native.getDiskLabel();
}
@@ -58,11 +59,11 @@ class Drive implements IPeripheral {
this.native.setDiskLabel();
}
public inline function setDiskLabel(label: String): Null<Error> {
public inline function setDiskLabel(label:String):Null<Error> {
try {
this.native.setDiskLabel(label);
return null;
} catch (e: Dynamic) {
} catch (e:Dynamic) {
return new Error("Invalid label");
}
}
@@ -79,7 +80,7 @@ class Drive implements IPeripheral {
return this.getMountPath();
}
public inline function getAudioTitle(): Null<String> {
public inline function getAudioTitle():Null<String> {
return this.native.getAudioTitle();
}
@@ -95,7 +96,7 @@ class Drive implements IPeripheral {
this.native.ejectDisk();
}
public inline function getDiskID(): Int {
public inline function getDiskID():Int {
return this.native.getDiskID();
}
}

View File

@@ -3,24 +3,24 @@ package kernel.peripherals;
import lib.exporter.ExportConfig;
import lib.exporter.IExportable;
class EnergyStorage implements IPeripheral implements IExportable{
public static inline final TYPE_NAME:String = "energyCell";
class EnergyStorage implements IPeripheral implements IExportable {
public static inline final TYPE_NAME:String = "energyCell";
private final addr:String;
private final native: cc.periphs.EnergyStorage;
private final addr:String;
private final native:cc.periphs.EnergyStorage;
public function new(addr: String) {
this.addr = addr;
this.native = cc.Peripheral.wrap(addr);
}
public function new(addr:String) {
this.addr = addr;
this.native = cc.Peripheral.wrap(addr);
}
public function getEnergy(): Int {
return this.native.getEnergy();
}
public function getEnergy():Int {
return this.native.getEnergy();
}
public function getEnergyCapacity(): Int {
return this.native.getEnergyCapacity();
}
public function getEnergyCapacity():Int {
return this.native.getEnergyCapacity();
}
public function getAddr():String {
return this.addr;
@@ -32,10 +32,10 @@ class EnergyStorage implements IPeripheral implements IExportable{
public function export():ExportConfig {
return {
getDelegates: [
"energy" => _ -> Number(this.getEnergy()),
"capacity" => _ -> Number(this.getEnergyCapacity()),
],
}
getDelegates: [
"energy" => _ -> Number(this.getEnergy()),
"capacity" => _ -> Number(this.getEnergyCapacity()),
],
}
}
}

View File

@@ -1,6 +1,6 @@
package kernel.peripherals;
interface IPeripheral {
public function getAddr(): String;
public function getType(): String;
public function getAddr():String;
public function getType():String;
}

View File

@@ -11,9 +11,9 @@ class Modem implements INetworkInterface implements IPeripheral {
public static inline final TYPE_NAME:String = "modem";
public final addr:String;
public var onMessage(default, null):Signal<{pack:GenericPackage,dist:Null<Float>}>;
public var onMessage(default, null):Signal<{pack:GenericPackage, dist:Null<Float>}>;
private final onMessageTrigger:SignalTrigger<{pack:GenericPackage,dist:Null<Float>}> = Signal.trigger();
private final onMessageTrigger:SignalTrigger<{pack:GenericPackage, dist:Null<Float>}> = Signal.trigger();
private final native:cc.periphs.Modem.Modem;
@:allow(kernel.peripherals)
@@ -22,9 +22,9 @@ class Modem implements INetworkInterface implements IPeripheral {
this.native = Peripheral.wrap(addr);
this.addr = addr;
KernelEvents.onModemMessage.handle(params ->{
try{
if (params.addr == this.addr){
KernelEvents.onModemMessage.handle(params -> {
try {
if (params.addr == this.addr) {
var pack:GenericPackage = {
fromID: params.message.fromID,
toID: params.message.toID,
@@ -36,7 +36,7 @@ class Modem implements INetworkInterface implements IPeripheral {
this.onMessageTrigger.trigger({pack: pack, dist: params.distance});
}
}catch(e:Dynamic){
} catch (e:Dynamic) {
Log.error("Error while parsing modem message");
}
});
@@ -79,9 +79,9 @@ class Modem implements INetworkInterface implements IPeripheral {
}
public function getBaseRoutingCost():Int {
if (this.native.isWireless()){
if (this.native.isWireless()) {
return 2; // Prefere messages over cable
}else{
} else {
return 1;
}
}

View File

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

View File

@@ -10,7 +10,7 @@ class Printer implements IPeripheral {
private final native:cc.periphs.Printer.Printer;
private final addr:String;
public function new(addr: String) {
public function new(addr:String) {
this.native = Peripheral.wrap(addr);
this.addr = addr;
}
@@ -23,36 +23,34 @@ class Printer implements IPeripheral {
return TYPE_NAME;
}
public function write(text: String){
public function write(text:String) {}
}
public function getCurserPos(): Pos {
public function getCurserPos():Pos {
return new Pos({x: 0, y: 0});
}
public function setCurserPos(pos: Pos){
public function setCurserPos(pos:Pos) {
this.native.setCursorPos(pos.x, pos.y);
}
public function getPageSize(): Rect {
public function getPageSize():Rect {
var pos = this.native.getPageSize();
return new Rect({x: 0, y: 0}, {x: pos.x, y: pos.y});
}
public function newPage(): Bool{
public function newPage():Bool {
return this.native.newPage();
}
public function endPage(): Bool{
public function endPage():Bool {
return this.native.endPage();
}
public function setPageTitle(title: String){
public function setPageTitle(title:String) {
this.native.setPageTitle(title);
}
public function getInkLevel(): Float{
public function getInkLevel():Float {
return this.native.getInkLevel();
}

View File

@@ -7,33 +7,33 @@ import lib.Color;
using tink.CoreApi;
abstract BundleMask(Int) from cc.Colors.Color to cc.Colors.Color {
abstract BundleMask(Int) from cc.Colors.Color to cc.Colors.Color {
public inline function new(i:Int) {
this = i;
}
@:from
public static function fromColor(c: Color) {
public static function fromColor(c:Color) {
return new BundleMask(c);
}
@:op(A + B)
@:op(A | B)
public inline function combine(rhs: BundleMask):BundleMask {
public inline function combine(rhs:BundleMask):BundleMask {
return this | rhs;
}
@:op(A + B)
@:op(A | B)
public inline function combineWithColor(rhs: Color):BundleMask {
public inline function combineWithColor(rhs:Color):BundleMask {
return this | rhs;
}
public function getComponents(): ReadOnlyArray<Color> {
var components: Array<Color> = [];
public function getComponents():ReadOnlyArray<Color> {
var components:Array<Color> = [];
var mask = 1;
for (i in 0...16){
if ((this & mask) > 0 ){
for (i in 0...16) {
if ((this & mask) > 0) {
components.push(mask);
}
mask = mask << 1;
@@ -57,19 +57,18 @@ class Redstone implements IPeripheral implements IExportable {
private var bundleInputState:BundleMask;
@:allow(kernel.peripherals)
private function new(side: Side) {
private function new(side:Side) {
this.addr = side;
this.onChange = this.onChangeTrigger.asSignal();
updateState();
KernelEvents.onRedstone.handle(()->{
if ((this.getAnalogInput() != this.analogInputState) || (this.bundleInputState != this.getBundledInput())){
KernelEvents.onRedstone.handle(() -> {
if ((this.getAnalogInput() != this.analogInputState) || (this.bundleInputState != this.getBundledInput())) {
updateState();
this.onChangeTrigger.trigger(null);
}
});
}
public function getAddr():String {
@@ -87,35 +86,35 @@ class Redstone implements IPeripheral implements IExportable {
public inline function setOutput(on:Bool):Void {
this.analogInputState = 15;
cc.Redstone.setOutput(this.addr,on);
cc.Redstone.setOutput(this.addr, on);
}
@export("output")
public inline function getOutput(): Bool {
public inline function getOutput():Bool {
return cc.Redstone.getOutput(this.addr);
}
@export("input")
public inline function getInput(): Bool {
public inline function getInput():Bool {
return cc.Redstone.getInput(this.addr);
}
public inline function setAnalogOutput(strength:Int): Void {
public inline function setAnalogOutput(strength:Int):Void {
this.analogInputState = strength;
cc.Redstone.setAnalogOutput(this.addr,strength);
cc.Redstone.setAnalogOutput(this.addr, strength);
}
public inline function getAnalogOutput(): Int {
public inline function getAnalogOutput():Int {
return cc.Redstone.getAnalogOutput(this.addr);
}
public inline function getAnalogInput(): Int {
public inline function getAnalogInput():Int {
return cc.Redstone.getAnalogInput(this.addr);
}
public inline function setBundledOutput(output: BundleMask) {
public inline function setBundledOutput(output:BundleMask) {
this.bundleInputState = output;
cc.Redstone.setBundledOutput(this.addr,output);
cc.Redstone.setBundledOutput(this.addr, output);
}
public inline function getBundledOutput():BundleMask {
@@ -126,7 +125,7 @@ class Redstone implements IPeripheral implements IExportable {
return cc.Redstone.getBundledInput(this.addr);
}
public inline function testBundledInput(mask: Color): Bool {
return cc.Redstone.testBundledInput(this.addr,mask);
public inline function testBundledInput(mask:Color):Bool {
return cc.Redstone.testBundledInput(this.addr, mask);
}
}

View File

@@ -15,7 +15,7 @@ class Screen implements TermWriteable implements IPeripheral {
private final nativ:cc.periphs.Monitor.Monitor;
private final addr:String;
private final onResizeTrigger:SignalTrigger<Vec2<Int>> = Signal.trigger();
private final onResizeTrigger:SignalTrigger<Vec2<Int>> = Signal.trigger();
public final onResize:Signal<Vec2<Int>>;
@@ -119,6 +119,6 @@ class Screen implements TermWriteable implements IPeripheral {
this.setBackgroundColor(Black);
this.setTextColor(White);
this.clear();
this.setCursorPos(0,0);
this.setCursorPos(0, 0);
}
}

View File

@@ -9,7 +9,7 @@ enum abstract Side(String) to String {
var Back = "back";
@:from
static public function fromString(s: String) {
static public function fromString(s:String) {
switch (s) {
case "top":
return Top;

View File

@@ -5,5 +5,5 @@ package kernel.ps;
**/
@:autoBuild(macros.DCEHack.DCEHack.dceInclude())
interface Process {
public function run(handle: ProcessHandle): Void;
public function run(handle:ProcessHandle):Void;
}

View File

@@ -4,32 +4,33 @@ import kernel.ps.ProcessManager.PID;
import kernel.ui.WindowContext;
import kernel.ui.WindowManager;
import haxe.ds.ReadOnlyArray;
using tink.CoreApi;
typedef HandleConfig = {
?args: Array<String>,
?onWrite: Callback<String>,
?onExit: Callback<Bool>,
?args:Array<String>,
?onWrite:Callback<String>,
?onExit:Callback<Bool>,
}
class ProcessHandle {
public var args(get,null): ReadOnlyArray<String>;
public var args(get, null):ReadOnlyArray<String>;
private final pid: PID;
private final pid:PID;
private final config:HandleConfig;
private final closeFuture: Future<Bool>;
private var closeFutureResolev: Bool -> Void;
private final windowContexts: Array<WindowContext> = [];
private final closeFuture:Future<Bool>;
private var closeFutureResolev:Bool->Void;
private final windowContexts:Array<WindowContext> = [];
private final cbLinks:Array<CallbackLink> = [];
private final deferFuncs:Array<Void -> Void> = [];
private var hasExited: Bool = false;
private final deferFuncs:Array<Void->Void> = [];
private var hasExited:Bool = false;
@:allow(kernel.ps.ProcessManager)
private function new(config: HandleConfig,pid: PID) {
private function new(config:HandleConfig, pid:PID) {
this.config = config;
this.pid = pid;
this.closeFuture = new Future<Bool>((trigger)->{
this.closeFuture = new Future<Bool>((trigger) -> {
this.closeFutureResolev = trigger;
return null;
});
@@ -39,42 +40,45 @@ class ProcessHandle {
}
}
public function onExit(): Future<Bool> {
public function onExit():Future<Bool> {
return this.closeFuture;
}
public function close(success: Bool = true): Void {
public function close(success:Bool = true):Void {
this.hasExited = true;
this.dispose();
EndOfLoop.endOfLoop(() ->{this.closeFutureResolev(success);});
EndOfLoop.endOfLoop(() -> {
this.closeFutureResolev(success);
});
ProcessManager.removeProcess(this.pid);
}
public function write(message: String): Void {
if (this.hasExited) return;
if (this.config.onWrite != null){
public function write(message:String):Void {
if (this.hasExited)
return;
if (this.config.onWrite != null) {
this.config.onWrite.invoke(message);
}
}
public function writeLine(message: String): Void {
public function writeLine(message:String):Void {
this.write(message + "\n");
}
public function createBufferdWindowContext(): WindowContext {
public function createBufferdWindowContext():WindowContext {
var ctx = WindowManager.createNewContext();
this.windowContexts.push(ctx);
return ctx;
}
public function createStatelessWindowContext(): {ctx:WindowContext, setRenderFunc: (() -> Void) -> Void, requestRender:() -> Void} {
public function createStatelessWindowContext():{ctx:WindowContext, setRenderFunc:(() -> Void)->Void, requestRender:() -> Void} {
var ctx = WindowManager.createNewStatelessContext();
this.windowContexts.push(ctx.ctx);
return ctx;
}
public function getWindowContexts(): ReadOnlyArray<WindowContext> {
public function getWindowContexts():ReadOnlyArray<WindowContext> {
return this.windowContexts;
}
@@ -88,15 +92,15 @@ class ProcessHandle {
}
}
public function getPid(): PID {
public function getPid():PID {
return this.pid;
}
public function addCallbackLink(link: CallbackLink) {
public function addCallbackLink(link:CallbackLink) {
this.cbLinks.push(link);
}
public function addDeferFunc(func: Void -> Void) {
public function addDeferFunc(func:Void->Void) {
this.deferFuncs.push(func);
}

View File

@@ -8,26 +8,26 @@ using tink.CoreApi;
typedef PID = Int;
class ProcessManager {
private static final processList = new Map<PID,ProcessHandle>();
private static final processList = new Map<PID, ProcessHandle>();
public static function run(process:Process, config: HandleConfig):PID {
public static function run(process:Process, config:HandleConfig):PID {
var pid = createPID();
var handle = new ProcessHandle(config, pid);
processList.set(pid, handle);
try{
try {
process.run(handle);
}catch(e:Dynamic){
} catch (e:Dynamic) {
Log.error("Error while running process: " + e);
handle.close(false);
}
return pid;
}
public static function kill(pid: PID) {
if (!processList.exists(pid)){
public static function kill(pid:PID) {
if (!processList.exists(pid)) {
Log.warn("Trying to kill non-existing process: " + pid);
return;
}
@@ -37,7 +37,7 @@ class ProcessManager {
handle.close();
}
private static function createPID(): PID {
private static function createPID():PID {
// TODO: better PID generation
// generate a random PID
@@ -45,7 +45,7 @@ class ProcessManager {
}
@:allow(kernel.ui.WindowManager)
private static function getProcess(pid:PID):Null<ProcessHandle>{
private static function getProcess(pid:PID):Null<ProcessHandle> {
return processList.get(pid);
}

View File

@@ -7,33 +7,32 @@ import kernel.binstore.BinStore;
using tink.CoreApi;
class Service {
public final binName:String;
public final name:String;
public final args:Array<String>;
public var pid:PID;
public var ps: Process;
public final binName:String;
public final name:String;
public final args:Array<String>;
public var pid:PID;
public var ps:Process;
@:allow(kernel.service.ServiceManager)
private function new(binName: String,name: String,?args: Array<String> ) {
this.binName = binName;
this.name = name;
this.args = args ?? [];
}
@:allow(kernel.service.ServiceManager)
private function new(binName:String, name:String, ?args:Array<String>) {
this.binName = binName;
this.name = name;
this.args = args ?? [];
}
public function start() {
var bin = BinStore.getBinByAlias(this.binName);
public function start() {
var bin = BinStore.getBinByAlias(this.binName);
if (bin == null){
throw new Error('Bin ${this.binName} not found');
}
this.ps = Type.createInstance(bin.c,this.args);
if (bin == null) {
throw new Error('Bin ${this.binName} not found');
}
this.pid = ProcessManager.run(this.ps,{});
}
this.ps = Type.createInstance(bin.c, this.args);
public function stop() {
ProcessManager.kill(this.pid);
}
this.pid = ProcessManager.run(this.ps, {});
}
public function stop() {
ProcessManager.kill(this.pid);
}
}

View File

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

View File

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

View File

@@ -103,15 +103,15 @@ class BufferedVirtualTermWriter implements VirtualTermWriter extends TermBuffer
}
public override function getCursorBlink():Bool {
if (isEnabled()){
if (isEnabled()) {
return target.getCursorBlink();
}else{
} else {
return super.getCursorBlink();
}
}
public override function setCursorBlink(blink:Bool) {
if (isEnabled()){
if (isEnabled()) {
target.setCursorBlink(blink);
}
super.setCursorBlink(blink);

View File

@@ -16,12 +16,12 @@ using tink.CoreApi;
class StatelessVirtualTermWriter implements VirtualTermWriter {
public var onResize(default, null):Signal<Vec2<Int>>;
private var onResizeTrigger: SignalTrigger<Vec2<Int>> = Signal.trigger();
private var onResizeTrigger:SignalTrigger<Vec2<Int>> = Signal.trigger();
private var target:TermWriteable;
private var enabled:Bool = false;
private var renderFunc:Null<Void->Void> = null;
private var renderRequested:Bool = false;
private var onResizeLink: CallbackLink;
private var onResizeLink:CallbackLink;
@:allow(kernel.ui)
private function new(?target:TermWriteable) {
@@ -29,7 +29,7 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
setTarget(target);
}
public function setRenderFunc(func: (Void->Void)) {
public function setRenderFunc(func:(Void->Void)) {
this.renderFunc = func;
}
@@ -43,7 +43,7 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
target.reset();
renderFunc();
renderRequested = false;
}else{
} else {
renderRequested = true;
}
}
@@ -59,7 +59,7 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
enabled = true;
if (renderFunc != null){
if (renderFunc != null) {
renderFunc();
}
@@ -101,11 +101,13 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
//
public inline function write(text:String) {
if (enabled) target.write(text);
if (enabled)
target.write(text);
}
public inline function scroll(y:Int) {
if (enabled) target.scroll(y);
if (enabled)
target.scroll(y);
}
public inline function getCursorPos():Pos {
@@ -113,7 +115,8 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
}
public inline function setCursorPos(x:Int, y:Int) {
if (enabled) target.setCursorPos(x, y);
if (enabled)
target.setCursorPos(x, y);
}
public inline function getCursorBlink():Bool {
@@ -121,7 +124,8 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
}
public inline function setCursorBlink(blink:Bool) {
if (enabled) target.setCursorBlink(blink);
if (enabled)
target.setCursorBlink(blink);
}
public inline function getSize():Vec2<Int> {
@@ -129,11 +133,13 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
}
public inline function clear() {
if (enabled) target.clear();
if (enabled)
target.clear();
}
public inline function clearLine() {
if (enabled) target.clearLine();
if (enabled)
target.clearLine();
}
public inline function getTextColor():Color {
@@ -141,7 +147,8 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
}
public inline function setTextColor(color:Color) {
if (enabled) target.setTextColor(color);
if (enabled)
target.setTextColor(color);
}
public inline function getBackgroundColor():Color {
@@ -149,7 +156,8 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
}
public inline function setBackgroundColor(color:Color) {
if (enabled) target.setBackgroundColor(color);
if (enabled)
target.setBackgroundColor(color);
}
public inline function isColor():Bool {
@@ -157,6 +165,7 @@ class StatelessVirtualTermWriter implements VirtualTermWriter {
}
public inline function reset() {
if (enabled) target.reset();
if (enabled)
target.reset();
}
}

View File

@@ -21,7 +21,7 @@ class TermBuffer implements TermWriteable {
private var cursorPos:Pos = {x: 0, y: 0};
private var currentTextColor:Color = White;
private var currentBgColor:Color = Black;
private var cursorBlink: Bool = false;
private var cursorBlink:Bool = false;
private var size:Vec2<Int> = {x: 51, y: 19}; // Default size set to default size of the main terminal
public final onResize:Signal<Vec2<Int>>;
@@ -178,6 +178,6 @@ class TermBuffer implements TermWriteable {
this.setBackgroundColor(Black);
this.setTextColor(White);
this.clear();
this.setCursorPos(0,0);
this.setCursorPos(0, 0);
}
}

View File

@@ -35,6 +35,7 @@ interface TermWriteable {
public function getBackgroundColor():Color;
public function setBackgroundColor(color:Color):Void;
public function isColor():Bool;
// public function setPaletteColor(...);
// public function getPaletteColor(color);

View File

@@ -15,7 +15,7 @@ using tink.CoreApi;
class WindowContext implements TermWriteable {
private final writer:VirtualTermWriter;
@:allow(kernel.ui.WindowManager) private var eventDelegate: Null<UIEventDelegate>;
@:allow(kernel.ui.WindowManager) private var eventDelegate:Null<UIEventDelegate>;
public var onClick(default, null):Signal<{button:ButtonType, pos:Pos}>;
public var onKey(default, null):Signal<{keyCode:Int, isHeld:Bool}>;
@@ -145,7 +145,7 @@ class WindowContext implements TermWriteable {
Delegate events to an UIEventDelegate.
Set to null to stop delegating events.
**/
public inline function delegateEvents(delegate: Null<UIEventDelegate>){
public inline function delegateEvents(delegate:Null<UIEventDelegate>) {
this.eventDelegate = delegate;
}
}

View File

@@ -15,16 +15,17 @@ class WindowManager {
Depends on: KernelEvents, Peripheral
**/
private static var currentMainContext:WindowContext;
private static final outputMap:Map<String, WindowContext> = new Map();
@:allow(kernel.Init)
private static function init() {
KernelEvents.onKey.handle(params -> {
if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){
if (currentMainContext.eventDelegate != null) {
var foo = currentMainContext.eventDelegate.getEventHandlers();
foo.onKey != null ? foo.onKey.invoke(params) : null;
}else{
} else {
currentMainContext.onKeyTrigger.trigger(params);
}
}
@@ -32,10 +33,10 @@ class WindowManager {
KernelEvents.onKeyUp.handle(keyCode -> {
if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){
if (currentMainContext.eventDelegate != null) {
var foo = currentMainContext.eventDelegate.getEventHandlers();
foo.onKeyUp != null ? foo.onKeyUp.invoke(keyCode) : null;
}else{
} else {
currentMainContext.onKeyUpTrigger.trigger(keyCode);
}
}
@@ -43,10 +44,10 @@ class WindowManager {
KernelEvents.onMouseClick.handle(params -> {
if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){
if (currentMainContext.eventDelegate != null) {
var foo = currentMainContext.eventDelegate.getEventHandlers();
foo.onClick != null ? foo.onClick.invoke(params) : null;
}else{
} else {
currentMainContext.onClickTrigger.trigger(params);
}
}
@@ -54,10 +55,10 @@ class WindowManager {
KernelEvents.onMouseDrag.handle(params -> {
if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){
if (currentMainContext.eventDelegate != null) {
var foo = currentMainContext.eventDelegate.getEventHandlers();
foo.onMouseDrag != null ? foo.onMouseDrag.invoke(params) : null;
}else{
} else {
currentMainContext.onMouseDragTrigger.trigger(params);
}
}
@@ -65,10 +66,10 @@ class WindowManager {
KernelEvents.onMouseScroll.handle(params -> {
if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){
if (currentMainContext.eventDelegate != null) {
var foo = currentMainContext.eventDelegate.getEventHandlers();
foo.onMouseScroll != null ? foo.onMouseScroll.invoke(params) : null;
}else{
} else {
currentMainContext.onMouseScrollTrigger.trigger(params);
}
}
@@ -76,10 +77,10 @@ class WindowManager {
KernelEvents.onMouseUp.handle(params -> {
if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){
if (currentMainContext.eventDelegate != null) {
var foo = currentMainContext.eventDelegate.getEventHandlers();
foo.onMouseUp != null ? foo.onMouseUp.invoke(params) : null;
}else{
} else {
currentMainContext.onMouseUpTrigger.trigger(params);
}
}
@@ -87,10 +88,10 @@ class WindowManager {
KernelEvents.onPaste.handle(text -> {
if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){
if (currentMainContext.eventDelegate != null) {
var foo = currentMainContext.eventDelegate.getEventHandlers();
foo.onPaste != null ? foo.onPaste.invoke(text) : null;
}else{
} else {
currentMainContext.onPasteTrigger.trigger(text);
}
}
@@ -102,10 +103,10 @@ class WindowManager {
KernelEvents.onChar.handle(char -> {
if (currentMainContext != null) {
if (currentMainContext.eventDelegate != null){
if (currentMainContext.eventDelegate != null) {
var foo = currentMainContext.eventDelegate.getEventHandlers();
foo.onChar != null ? foo.onChar.invoke(char) : null;
}else{
} else {
currentMainContext.onCharTrigger.trigger(char);
}
}
@@ -125,7 +126,7 @@ class WindowManager {
return newContext;
}
public static function createNewStatelessContext():{ctx:WindowContext, setRenderFunc:(() -> Void) -> Void, requestRender:Void->Void} {
public static function createNewStatelessContext():{ctx:WindowContext, setRenderFunc:(() -> Void)->Void, requestRender:Void->Void} {
var writer = new StatelessVirtualTermWriter();
var newContext = new WindowContext(writer);
@@ -164,7 +165,7 @@ class WindowManager {
context.enable();
}
public static function getContextByPID(pid: PID): ReadOnlyArray<WindowContext> {
public static function getContextByPID(pid:PID):ReadOnlyArray<WindowContext> {
var handle = ProcessManager.getProcess(pid);
if (handle == null) {
return [];