This commit is contained in:
Djeeberjr 2022-02-21 15:35:37 +01:00
parent f21e49c520
commit 0ad907f74a
33 changed files with 788 additions and 815 deletions

View File

@ -3,12 +3,12 @@ const http = require('http');
function time() { function time() {
let now = new Date(); let now = new Date();
return `${now.getHours().toString().padStart(2,"0")}:${now.getMinutes().toString().padStart(2,0)}:${now.getSeconds().toString().padStart(2,0)}`; return `${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, 0)}:${now.getSeconds().toString().padStart(2, 0)}`;
} }
const server = http.createServer((req,res)=>{ const server = http.createServer((req, res) => {
if (req.method != "POST" ){ if (req.method != "POST") {
res.writeHead(400); res.writeHead(400);
return; return;
} }
@ -16,13 +16,13 @@ const server = http.createServer((req,res)=>{
let data = ""; let data = "";
req.on('data', chunk => { req.on('data', chunk => {
data += chunk; data += chunk;
}) })
req.on('end', () => { req.on('end', () => {
console.log(`[${time()}]${data}`); console.log(`[${time()}]${data}`);
res.writeHead(200); res.writeHead(200);
res.end(); res.end();
}) })
}); });

View File

@ -1,7 +1,7 @@
package kernel; package kernel;
enum ButtonType { enum ButtonType {
Left; Left;
Middle; Middle;
Right; Right;
} }

View File

@ -6,17 +6,17 @@ import kernel.peripherals.Peripherals.Peripheral;
import kernel.net.Net; import kernel.net.Net;
class Init { 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.
KernelEvents.instance = new KernelEvents(); KernelEvents.instance = new KernelEvents();
Peripheral.instance = new Peripheral(); Peripheral.instance = new Peripheral();
WindowManager.instance = new WindowManager(); WindowManager.instance = new WindowManager();
MainTerm.instance = new MainTerm(); MainTerm.instance = new MainTerm();
Net.instance = new Net(); Net.instance = new Net();
Log.init(); Log.init();
Debug.printBuildInfo(); Debug.printBuildInfo();
} }
} }

View File

@ -2,6 +2,7 @@ package kernel;
import util.Vec.Vec2; import util.Vec.Vec2;
import haxe.Exception; import haxe.Exception;
using tink.CoreApi; using tink.CoreApi;
import cc.OS; import cc.OS;
@ -11,75 +12,87 @@ using lua.Table;
/** /**
Class for interacting with the native pullEvent system. Class for interacting with the native pullEvent system.
**/ **/
class KernelEvents{ class KernelEvents {
public static var instance:KernelEvents; public static var instance:KernelEvents;
public final onAlarm: Signal<Int>; public final onAlarm:Signal<Int>;
public final onChar: Signal<String>; public final onChar:Signal<String>;
public final onDisk: Signal<String>; public final onDisk:Signal<String>;
public final onDiskEject: Signal<String>; public final onDiskEject:Signal<String>;
public final onHttpCheck: Signal<{url:String,success:Bool,failReason:Any}>; public final onHttpCheck:Signal<{url:String, success:Bool, failReason:Any}>;
public final onHttpFailure: Signal<{url:String,failReason:String,handle:Any}>; public final onHttpFailure:Signal<{url:String, failReason:String, handle:Any}>;
public final onHttpSuccess: Signal<{url:String,handle:Any}>; public final onHttpSuccess:Signal<{url:String, handle:Any}>;
public final onKey: Signal<{keyCode: Int,isHeld:Bool}>; public final onKey:Signal<{keyCode:Int, isHeld:Bool}>;
public final onKeyUp: Signal<Int>; public final onKeyUp:Signal<Int>;
public final onModemMessage: Signal<{addr: String,channel:Int, replyChannel:Int,message:Dynamic,distance:Int}>; public final onModemMessage:Signal<{
public final onMonitorResize: Signal<String>; addr:String,
public final onMonitorTouch: Signal<{addr:String,pos: Vec2<Int>}>; channel:Int,
public final onMouseClick: Signal<{button:ButtonType,pos: Vec2<Int>}>; replyChannel:Int,
public final onMouseDrag: Signal<{button:ButtonType,pos: Vec2<Int>}>; message:Dynamic,
public final onMouseScroll: Signal<{dir:Int,pos: Vec2<Int>}>; distance:Int
public final onMouseUp: Signal<{button:ButtonType,pos: Vec2<Int>}>; }>;
public final onPaste: Signal<String>; public final onMonitorResize:Signal<String>;
public final onPeripheral: Signal<String>; public final onMonitorTouch:Signal<{addr:String, pos:Vec2<Int>}>;
public final onPeripheralDetach: Signal<String>; public final onMouseClick:Signal<{button:ButtonType, pos:Vec2<Int>}>;
public final onRednetMessage: Signal<{sender:Int,message:Any,protocol:Any}>; public final onMouseDrag:Signal<{button:ButtonType, pos:Vec2<Int>}>;
public final onRedstone: Signal<Noise>; public final onMouseScroll:Signal<{dir:Int, pos:Vec2<Int>}>;
public final onSpeakerAudioEmpty: Signal<String>; public final onMouseUp:Signal<{button:ButtonType, pos:Vec2<Int>}>;
public final onTaskComplete: Signal<{id:Int,success:Bool,failedReason:String}>; public final onPaste:Signal<String>;
public final onTermResize: Signal<Noise>; public final onPeripheral:Signal<String>;
public final onTerminate: Signal<Noise>; public final onPeripheralDetach:Signal<String>;
public final onTimer: Signal<Int>; public final onRednetMessage:Signal<{sender:Int, message:Any, protocol:Any}>;
public final onTurtleInventory: Signal<Noise>; public final onRedstone:Signal<Noise>;
public final onWebsocketClose: Signal<String>; public final onSpeakerAudioEmpty:Signal<String>;
public final onWebsocketFailure: Signal<{url:String,failReason:String}>; public final onTaskComplete:Signal<{id:Int, success:Bool, failedReason:String}>;
public final onWebsocketMessage: Signal<{url:String,message:String,isBinary:Bool}>; public final onTermResize:Signal<Noise>;
public final onWebsocketSuccess: Signal<{url:String,handle:Any}>; public final onTerminate:Signal<Noise>;
public final onTimer:Signal<Int>;
public final onTurtleInventory:Signal<Noise>;
public final onWebsocketClose:Signal<String>;
public final onWebsocketFailure:Signal<{url:String, failReason:String}>;
public final onWebsocketMessage:Signal<{url:String, message:String, isBinary:Bool}>;
public final onWebsocketSuccess:Signal<{url:String, handle:Any}>;
private final onAlarmTrigger: SignalTrigger<Int> = Signal.trigger(); private final onAlarmTrigger:SignalTrigger<Int> = Signal.trigger();
private final onCharTrigger: SignalTrigger<String> = Signal.trigger(); private final onCharTrigger:SignalTrigger<String> = Signal.trigger();
private final onDiskTrigger: SignalTrigger<String> = Signal.trigger(); private final onDiskTrigger:SignalTrigger<String> = Signal.trigger();
private final onDiskEjectTrigger: SignalTrigger<String> = Signal.trigger(); private final onDiskEjectTrigger:SignalTrigger<String> = Signal.trigger();
private final onHttpCheckTrigger: SignalTrigger<{url:String,success:Bool,failReason:Any}> = Signal.trigger(); private final onHttpCheckTrigger:SignalTrigger<{url:String, success:Bool, failReason:Any}> = Signal.trigger();
private final onHttpFailureTrigger: SignalTrigger<{url:String,failReason:String,handle:Any}> = Signal.trigger(); private final onHttpFailureTrigger:SignalTrigger<{url:String, failReason:String, handle:Any}> = Signal.trigger();
private final onHttpSuccessTrigger: SignalTrigger<{url:String,handle:Any}> = Signal.trigger(); private final onHttpSuccessTrigger:SignalTrigger<{url:String, handle:Any}> = Signal.trigger();
private final onKeyTrigger: SignalTrigger<{keyCode: Int,isHeld:Bool}> = Signal.trigger(); private final onKeyTrigger:SignalTrigger<{keyCode:Int, isHeld:Bool}> = Signal.trigger();
private final onKeyUpTrigger: SignalTrigger<Int> = Signal.trigger(); private final onKeyUpTrigger:SignalTrigger<Int> = Signal.trigger();
private final onModemMessageTrigger: SignalTrigger<{addr: String,channel:Int, replyChannel:Int,message:Dynamic,distance:Int}> = Signal.trigger(); private final onModemMessageTrigger:SignalTrigger<{
private final onMonitorResizeTrigger: SignalTrigger<String> = Signal.trigger(); addr:String,
private final onMonitorTouchTrigger: SignalTrigger<{addr:String,pos: Vec2<Int>}> = Signal.trigger(); channel:Int,
private final onMouseClickTrigger: SignalTrigger<{button:ButtonType,pos: Vec2<Int>}> = Signal.trigger(); replyChannel:Int,
private final onMouseDragTrigger: SignalTrigger<{button:ButtonType,pos: Vec2<Int>}> = Signal.trigger(); message:Dynamic,
private final onMouseScrollTrigger: SignalTrigger<{dir:Int,pos: Vec2<Int>}> = Signal.trigger(); distance:Int
private final onMouseUpTrigger: SignalTrigger<{button:ButtonType,pos: Vec2<Int>}> = Signal.trigger(); }> = Signal.trigger();
private final onPasteTrigger: SignalTrigger<String> = Signal.trigger(); private final onMonitorResizeTrigger:SignalTrigger<String> = Signal.trigger();
private final onPeripheralTrigger: SignalTrigger<String> = Signal.trigger(); private final onMonitorTouchTrigger:SignalTrigger<{addr:String, pos:Vec2<Int>}> = Signal.trigger();
private final onPeripheralDetachTrigger: SignalTrigger<String> = Signal.trigger(); private final onMouseClickTrigger:SignalTrigger<{button:ButtonType, pos:Vec2<Int>}> = Signal.trigger();
private final onRednetMessageTrigger: SignalTrigger<{sender:Int,message:Any,protocol:Any}> = Signal.trigger(); private final onMouseDragTrigger:SignalTrigger<{button:ButtonType, pos:Vec2<Int>}> = Signal.trigger();
private final onRedstoneTrigger: SignalTrigger<Noise> = Signal.trigger(); private final onMouseScrollTrigger:SignalTrigger<{dir:Int, pos:Vec2<Int>}> = Signal.trigger();
private final onSpeakerAudioEmptyTrigger: SignalTrigger<String> = Signal.trigger(); private final onMouseUpTrigger:SignalTrigger<{button:ButtonType, pos:Vec2<Int>}> = Signal.trigger();
private final onTaskCompleteTrigger: SignalTrigger<{id:Int,success:Bool,failedReason:String}> = Signal.trigger(); private final onPasteTrigger:SignalTrigger<String> = Signal.trigger();
private final onTermResizeTrigger: SignalTrigger<Noise> = Signal.trigger(); private final onPeripheralTrigger:SignalTrigger<String> = Signal.trigger();
private final onTerminateTrigger: SignalTrigger<Noise> = Signal.trigger(); private final onPeripheralDetachTrigger:SignalTrigger<String> = Signal.trigger();
private final onTimerTrigger: SignalTrigger<Int> = Signal.trigger(); private final onRednetMessageTrigger:SignalTrigger<{sender:Int, message:Any, protocol:Any}> = Signal.trigger();
private final onTurtleInventoryTrigger: SignalTrigger<Noise> = Signal.trigger(); private final onRedstoneTrigger:SignalTrigger<Noise> = Signal.trigger();
private final onWebsocketCloseTrigger: SignalTrigger<String> = Signal.trigger(); private final onSpeakerAudioEmptyTrigger:SignalTrigger<String> = Signal.trigger();
private final onWebsocketFailureTrigger: SignalTrigger<{url:String,failReason:String}> = Signal.trigger(); private final onTaskCompleteTrigger:SignalTrigger<{id:Int, success:Bool, failedReason:String}> = Signal.trigger();
private final onWebsocketMessageTrigger: SignalTrigger<{url:String,message:String,isBinary:Bool}> = Signal.trigger(); private final onTermResizeTrigger:SignalTrigger<Noise> = Signal.trigger();
private final onWebsocketSuccessTrigger: SignalTrigger<{url:String,handle:Any}> = Signal.trigger(); private final onTerminateTrigger:SignalTrigger<Noise> = Signal.trigger();
private final onTimerTrigger:SignalTrigger<Int> = Signal.trigger();
private final onTurtleInventoryTrigger:SignalTrigger<Noise> = Signal.trigger();
private final onWebsocketCloseTrigger:SignalTrigger<String> = Signal.trigger();
private final onWebsocketFailureTrigger:SignalTrigger<{url:String, failReason:String}> = Signal.trigger();
private final onWebsocketMessageTrigger:SignalTrigger<{url:String, message:String, isBinary:Bool}> = Signal.trigger();
private final onWebsocketSuccessTrigger:SignalTrigger<{url:String, handle:Any}> = Signal.trigger();
@:allow(kernel.Init) @:allow(kernel.Init)
private function new () { private function new() {
this.onAlarm = onAlarmTrigger.asSignal(); this.onAlarm = onAlarmTrigger.asSignal();
this.onChar = onCharTrigger.asSignal(); this.onChar = onCharTrigger.asSignal();
this.onDisk = onDiskTrigger.asSignal(); this.onDisk = onDiskTrigger.asSignal();
@ -117,7 +130,7 @@ class KernelEvents{
Start pulling events. Blocking. Start pulling events. Blocking.
**/ **/
public function startEventLoop() { public function startEventLoop() {
while (true){ while (true) {
var event:Table<Int, Dynamic> = OS.pullEventRaw(); var event:Table<Int, Dynamic> = OS.pullEventRaw();
var eventName:String = event[1]; var eventName:String = event[1];
@ -132,29 +145,35 @@ class KernelEvents{
case "disk_eject": case "disk_eject":
this.onDiskEjectTrigger.trigger(event[2]); this.onDiskEjectTrigger.trigger(event[2]);
case "http_check": case "http_check":
this.onHttpCheckTrigger.trigger({url: event[2],success: event[3],failReason: event[4]}); this.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]}); this.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]}); this.onHttpSuccessTrigger.trigger({url: event[2], handle: event[3]});
case "key": case "key":
this.onKeyTrigger.trigger({keyCode: event[2],isHeld: event[3]}); this.onKeyTrigger.trigger({keyCode: event[2], isHeld: event[3]});
case "key_up": case "key_up":
this.onKeyUpTrigger.trigger(event[2]); this.onKeyUpTrigger.trigger(event[2]);
case "modem_message": case "modem_message":
this.onModemMessageTrigger.trigger({addr: event[2],channel: event[3],replyChannel: event[4],message: event[5],distance: event[6]}); this.onModemMessageTrigger.trigger({
addr: event[2],
channel: event[3],
replyChannel: event[4],
message: event[5],
distance: event[6]
});
case "monitor_resize": case "monitor_resize":
this.onMonitorResizeTrigger.trigger(event[2]); this.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}}); this.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}}); this.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}}); this.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}}); this.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}}); this.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]); this.onPasteTrigger.trigger(event[2]);
case "peripheral": case "peripheral":
@ -162,13 +181,13 @@ class KernelEvents{
case "peripheral_detach": case "peripheral_detach":
this.onPeripheralDetachTrigger.trigger(event[2]); this.onPeripheralDetachTrigger.trigger(event[2]);
case "rednet_message": case "rednet_message":
this.onRednetMessageTrigger.trigger({sender: event[2],message: event[3],protocol: event[4]}); this.onRednetMessageTrigger.trigger({sender: event[2], message: event[3], protocol: event[4]});
case "redstone": case "redstone":
this.onRedstoneTrigger.trigger(null); this.onRedstoneTrigger.trigger(null);
case "speaker_audio_empty": case "speaker_audio_empty":
this.onSpeakerAudioEmptyTrigger.trigger(event[2]); this.onSpeakerAudioEmptyTrigger.trigger(event[2]);
case "task_complete": case "task_complete":
this.onTaskCompleteTrigger.trigger({id: event[2],success: event[3],failedReason: event[4]}); this.onTaskCompleteTrigger.trigger({id: event[2], success: event[3], failedReason: event[4]});
case "term_resize": case "term_resize":
this.onTermResizeTrigger.trigger(null); this.onTermResizeTrigger.trigger(null);
case "terminate": case "terminate":
@ -180,18 +199,18 @@ class KernelEvents{
case "websocket_closed": case "websocket_closed":
this.onWebsocketCloseTrigger.trigger(event[2]); this.onWebsocketCloseTrigger.trigger(event[2]);
case "websocket_failure": case "websocket_failure":
this.onWebsocketFailureTrigger.trigger({url: event[2],failReason: event[3]}); this.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]}); this.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]}); this.onWebsocketSuccessTrigger.trigger({url: event[2], handle: event[3]});
default: default:
Log.error("Unknown cc event: " + eventName); Log.error("Unknown cc event: " + eventName);
} }
} }
} }
private static function ccButtonToEnum(button: Dynamic): ButtonType { private static function ccButtonToEnum(button:Dynamic):ButtonType {
switch button { switch button {
case 1: case 1:
return Left; return Left;

View File

@ -19,39 +19,39 @@ class Log {
Log.writer = new TermIO(Log.context); Log.writer = new TermIO(Log.context);
} }
private static function setMainoutout(newOutput: TermWriteable) { private static function setMainoutout(newOutput:TermWriteable) {
writer = new TermIO(newOutput); writer = new TermIO(newOutput);
} }
public static function info(msg: Dynamic, ?pos:haxe.PosInfos){ public static function info(msg:Dynamic, ?pos:haxe.PosInfos) {
writer.writeLn("[INFO]["+pos.className+"]: "+Std.string(msg)); writer.writeLn("[INFO][" + pos.className + "]: " + Std.string(msg));
#if webconsole #if webconsole
Debug.printWeb("[INFO]["+pos.className+"]: "+Std.string(msg)); Debug.printWeb("[INFO][" + pos.className + "]: " + Std.string(msg));
#end #end
} }
public static function warn(msg: Dynamic, ?pos:haxe.PosInfos){ public static function warn(msg:Dynamic, ?pos:haxe.PosInfos) {
writer.writeLn("[WARN]["+pos.className+"]: "+Std.string(msg),Yellow); writer.writeLn("[WARN][" + pos.className + "]: " + Std.string(msg), Yellow);
#if webconsole #if webconsole
Debug.printWeb("[WARN]["+pos.className+"]: "+Std.string(msg)); Debug.printWeb("[WARN][" + pos.className + "]: " + Std.string(msg));
#end #end
} }
public static function error(msg: Dynamic,?pos:haxe.PosInfos) { public static function error(msg:Dynamic, ?pos:haxe.PosInfos) {
writer.writeLn("[ERRO]["+pos.className+"]: "+Std.string(msg),Red); writer.writeLn("[ERRO][" + pos.className + "]: " + Std.string(msg), Red);
#if webconsole #if webconsole
Debug.printWeb("[ERRO]["+pos.className+"]: "+Std.string(msg)); Debug.printWeb("[ERRO][" + pos.className + "]: " + Std.string(msg));
#end #end
} }
public static function debug(msg: Dynamic,?pos:haxe.PosInfos) { public static function debug(msg:Dynamic, ?pos:haxe.PosInfos) {
writer.writeLn("[DEBG]["+pos.className+"]: "+Std.string(msg),Gray); writer.writeLn("[DEBG][" + pos.className + "]: " + Std.string(msg), Gray);
#if webconsole #if webconsole
Debug.printWeb("[DEBG]["+pos.className+"]: "+Std.string(msg)); Debug.printWeb("[DEBG][" + pos.className + "]: " + Std.string(msg));
#end #end
} }
public static function moveToOutput(addr: String) { public static function moveToOutput(addr:String) {
WindowManager.instance.focusContextToOutput(context,addr); WindowManager.instance.focusContextToOutput(context, addr);
} }
} }

View File

@ -10,8 +10,9 @@ import util.Color;
/** /**
Represents the main computer screen. Represents the main computer screen.
**/ **/
class MainTerm implements TermWriteable{ class MainTerm implements TermWriteable {
public static var instance:MainTerm; public static var instance:MainTerm;
public var onResize(default, null):Signal<Vec2<Int>>; public var onResize(default, null):Signal<Vec2<Int>>;
private var onResizeTrigger:SignalTrigger<Vec2<Int>>; private var onResizeTrigger:SignalTrigger<Vec2<Int>>;
@ -21,72 +22,71 @@ 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.instance.onTermResize.handle(_ -> {
onResizeTrigger.trigger(getSize()); onResizeTrigger.trigger(getSize());
}); });
} }
public function write(text:String) { public function write(text:String) {
Term.write(text); Term.write(text);
} }
public function scroll(y:Int) { public function scroll(y:Int) {
Term.scroll(y); Term.scroll(y);
} }
public function getCursorPos():Vec2<Int> { public function getCursorPos():Vec2<Int> {
var rtn = Term.getCursorPos(); var rtn = Term.getCursorPos();
return { return {
x: rtn.x - 1, x: rtn.x - 1,
y: rtn.y - 1 y: rtn.y - 1
} }
} }
public function setCursorPos(x:Int, y:Int) { public function setCursorPos(x:Int, y:Int) {
Term.setCursorPos(x + 1,y + 1); Term.setCursorPos(x + 1, y + 1);
} }
public function getCursorBlink():Bool { public function getCursorBlink():Bool {
// Missing in api // Missing in api
throw new haxe.exceptions.NotImplementedException(); throw new haxe.exceptions.NotImplementedException();
} }
public function setCursorBlink(blink:Bool) { public function setCursorBlink(blink:Bool) {
Term.setCursorBlink(blink); Term.setCursorBlink(blink);
} }
public function getSize():Vec2<Int> { public function getSize():Vec2<Int> {
var rtn = Term.getSize(); var rtn = Term.getSize();
return { return {
x: rtn.width, x: rtn.width,
y: rtn.height, y: rtn.height,
} }
} }
public function clear() { public function clear() {
Term.clear(); Term.clear();
} }
public function clearLine() { public function clearLine() {
Term.clearLine(); Term.clearLine();
} }
public function getTextColor():Color { public function getTextColor():Color {
return ColorConvert.ccToColor(Term.getTextColor()); return ColorConvert.ccToColor(Term.getTextColor());
} }
public function setTextColor(colour:Color) { public function setTextColor(colour:Color) {
Term.setTextColor(ColorConvert.colorToCC(colour)); Term.setTextColor(ColorConvert.colorToCC(colour));
} }
public function getBackgroundColor():Color { public function getBackgroundColor():Color {
return ColorConvert.ccToColor(Term.getBackgroundColor()); return ColorConvert.ccToColor(Term.getBackgroundColor());
} }
public function setBackgroundColor(color:Color) { public function setBackgroundColor(color:Color) {
Term.setBackgroundColor(ColorConvert.colorToCC(color)); Term.setBackgroundColor(ColorConvert.colorToCC(color));
} }
public function isColor():Bool { public function isColor():Bool {
return Term.isColor(); return Term.isColor();

View File

@ -15,12 +15,12 @@ class Timer {
/** /**
Create new timer with timeout in seconds. Create new timer with timeout in seconds.
**/ **/
public function new(timeout: Int, callback: Callback<Noise>) { public function new(timeout:Int, callback:Callback<Noise>) {
timerID = OS.startTimer(timeout); timerID = OS.startTimer(timeout);
this.callback = callback; this.callback = callback;
timerLink = KernelEvents.instance.onTimer.handle(timerID ->{ timerLink = KernelEvents.instance.onTimer.handle(timerID -> {
if (this.timerID == timerID){ if (this.timerID == timerID) {
callback.invoke(null); callback.invoke(null);
timerLink.cancel(); timerLink.cancel();
} }

View File

@ -16,13 +16,13 @@ using util.Extender.LambdaExtender;
Class responsible for everything network related. Class responsible for everything network related.
Used to send and recceive packages. Used to send and recceive packages.
**/ **/
class Net{ class Net {
public static var instance:Net; public static var instance:Net;
@:allow(kernel.Init) @:allow(kernel.Init)
private function new () { private function new() {
KernelEvents.instance.onModemMessage.handle(params ->{ KernelEvents.instance.onModemMessage.handle(params -> {
var pack: Package = { var pack:Package = {
fromID: params.replyChannel, fromID: params.replyChannel,
toID: params.channel, toID: params.channel,
msgID: params.message.msgID, msgID: params.message.msgID,
@ -30,7 +30,7 @@ class Net{
data: params.message.data, data: params.message.data,
}; };
handelIncomming(pack,params.addr); handelIncomming(pack, params.addr);
}); });
allModems = Peripheral.instance.getModems(); allModems = Peripheral.instance.getModems();
@ -42,27 +42,26 @@ class Net{
public static inline final MESSAGE_TIMEOUT:Int = 3; public static inline final MESSAGE_TIMEOUT:Int = 3;
private var networkID:Int = OS.getComputerID(); private var networkID:Int = OS.getComputerID();
private var responseBus: util.EventBus<Package> = new EventBus(); private var responseBus:util.EventBus<Package> = new EventBus();
private var protoHandlers: Map<String,Package -> Void> = new Map(); private var protoHandlers:Map<String, Package->Void> = new Map();
private var allModems:Array<kernel.peripherals.Modem>; private var allModems:Array<kernel.peripherals.Modem>;
private var routingTable: Map<Int,kernel.peripherals.Modem> = new Map(); private var routingTable:Map<Int, kernel.peripherals.Modem> = new Map();
private function handelIncomming(pack: Package, ?addr:String) { private function handelIncomming(pack:Package, ?addr:String) {
switch pack.type { switch pack.type {
case Data(_): case Data(_):
routeTo(pack); routeTo(pack);
case DataNoResponse(_): case DataNoResponse(_):
routeTo(pack); routeTo(pack);
case Response | RouteDiscoverResponse: case Response | RouteDiscoverResponse:
responseBus.emit(Std.string(pack.msgID),pack); responseBus.emit(Std.string(pack.msgID), pack);
case RouteDiscover: case RouteDiscover:
handleRoute(pack,addr); handleRoute(pack, addr);
} }
} }
private function newRoutPackage(): Package { private function newRoutPackage():Package {
var pack: Package = { var pack:Package = {
type: RouteDiscover, type: RouteDiscover,
toID: BRODCAST_PORT, toID: BRODCAST_PORT,
msgID: generateMessageID(), msgID: generateMessageID(),
@ -77,24 +76,24 @@ class Net{
for (modem in allModems) { for (modem in allModems) {
var pack = newRoutPackage(); var pack = newRoutPackage();
var timeout: Timer = null; var timeout:Timer = null;
var responeListner = responseBus.on(Std.string(pack.msgID),pack -> { var responeListner = responseBus.on(Std.string(pack.msgID), pack -> {
addRoute(pack.fromID,modem.addr); addRoute(pack.fromID, modem.addr);
}); });
timeout = new Timer(MESSAGE_TIMEOUT,() -> { timeout = new Timer(MESSAGE_TIMEOUT, () -> {
responseBus.removeListner(responeListner); responseBus.removeListner(responeListner);
}); });
modem.transmit(BRODCAST_PORT,OS.getComputerID(),pack); modem.transmit(BRODCAST_PORT, OS.getComputerID(), pack);
} }
} }
private function handleRoute(pack: Package, addr: String) { private function handleRoute(pack:Package, addr:String) {
addRoute(pack.fromID,addr); addRoute(pack.fromID, addr);
// Respond to peer // Respond to peer
var response: Package = { var response:Package = {
toID: pack.fromID, toID: pack.fromID,
fromID: OS.getComputerID(), fromID: OS.getComputerID(),
msgID: pack.msgID, msgID: pack.msgID,
@ -103,20 +102,20 @@ class Net{
} }
for (reponseModem in allModems.filter(m -> m.addr == addr)) { for (reponseModem in allModems.filter(m -> m.addr == addr)) {
reponseModem.transmit(pack.fromID,networkID,response); reponseModem.transmit(pack.fromID, networkID, response);
} }
} }
private function addRoute(toID: Int,addr: String) { private function addRoute(toID:Int, addr:String) {
Log.debug("Added new route to "+toID+" via "+addr); Log.debug("Added new route to " + toID + " via " + addr);
routingTable.set(toID,allModems.find(item -> item.addr == addr)); routingTable.set(toID, allModems.find(item -> item.addr == addr));
} }
public function getAllNeighbors(): Array<Int> { public function getAllNeighbors():Array<Int> {
return routingTable.mapi((index, item) -> index); return routingTable.mapi((index, item) -> index);
} }
private function generateMessageID(): Int { private function generateMessageID():Int {
return Std.random(2147483647); // TODO: better uniqe number return Std.random(2147483647); // TODO: better uniqe number
} }
@ -133,9 +132,8 @@ class Net{
/** /**
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 function sendAndForget(dest:Int, proto:String, data:Dynamic) {
var pack:Package = {
var pack: Package = {
toID: dest, toID: dest,
fromID: networkID, fromID: networkID,
msgID: generateMessageID(), msgID: generateMessageID(),
@ -146,8 +144,8 @@ class Net{
sendRaw(pack); sendRaw(pack);
} }
public function respondTo(pack: Package,data: Dynamic) { public function respondTo(pack:Package, 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;
} }
@ -157,8 +155,8 @@ class Net{
sendRaw(response); sendRaw(response);
} }
private function routeTo(pack: Package) { private function routeTo(pack:Package) {
var proto: String = switch pack.type { var proto:String = switch pack.type {
case Data(proto): case Data(proto):
proto; proto;
case DataNoResponse(proto): case DataNoResponse(proto):
@ -167,31 +165,30 @@ class Net{
return; return;
} }
if (!protoHandlers.exists(proto) && protoHandlers[proto] != null){ if (!protoHandlers.exists(proto) && protoHandlers[proto] != null) {
return; return;
} }
protoHandlers[proto](pack); protoHandlers[proto](pack);
} }
private function sendRaw(pack: Package){ private function sendRaw(pack:Package) {
if (pack.toID == networkID) {
if (pack.toID == networkID){
// Loopback // Loopback
handelIncomming(pack); handelIncomming(pack);
}else{ } else {
if (routingTable.exists(pack.toID)){ if (routingTable.exists(pack.toID)) {
routingTable[pack.toID].transmit(pack.toID,pack.fromID,pack); routingTable[pack.toID].transmit(pack.toID, pack.fromID, pack);
}else{ } else {
// Route not found // Route not found
// TODO: forward package or report not reachable // TODO: forward package or report not reachable
} }
} }
} }
public function sendAndAwait(dest: Int,proto:String,data: Dynamic): Promise<Package> { public function sendAndAwait(dest:Int, proto:String, data:Dynamic):Promise<Package> {
return new Promise<Package>((resolve, reject) -> { return new Promise<Package>((resolve, reject) -> {
var pack: Package = { var pack:Package = {
toID: dest, toID: dest,
fromID: networkID, fromID: networkID,
msgID: generateMessageID(), msgID: generateMessageID(),
@ -199,15 +196,15 @@ class Net{
data: data data: data
} }
var timeout: Timer = null; var timeout:Timer = null;
var responeListner = responseBus.once(Std.string(pack.msgID),p -> { var responeListner = responseBus.once(Std.string(pack.msgID), p -> {
resolve(p); resolve(p);
if (timeout != null){ if (timeout != null) {
timeout.cancle(); timeout.cancle();
} }
}); });
timeout = new Timer(MESSAGE_TIMEOUT,() -> { timeout = new Timer(MESSAGE_TIMEOUT, () -> {
responseBus.removeListner(responeListner); responseBus.removeListner(responeListner);
reject(new Exception("Timeout")); reject(new Exception("Timeout"));
}); });
@ -216,8 +213,8 @@ class Net{
}); });
} }
public function registerProto(proto: String,cb: Package -> Void) { public function registerProto(proto:String, cb:Package->Void) {
if (protoHandlers.exists(proto)){ if (protoHandlers.exists(proto)) {
// Failed. Handler already exist. // Failed. Handler already exist.
// TODO: return error // TODO: return error
return; return;
@ -226,7 +223,7 @@ class Net{
protoHandlers[proto] = cb; protoHandlers[proto] = cb;
} }
public function removeProto(proto: String) { public function removeProto(proto:String) {
protoHandlers.remove(proto); protoHandlers.remove(proto);
} }
} }

View File

@ -1,8 +1,8 @@
package kernel.net; package kernel.net;
enum PackageTypes { enum PackageTypes {
Data(proto: String); Data(proto:String);
DataNoResponse(proto: String); DataNoResponse(proto:String);
Response; Response;
RouteDiscover(); RouteDiscover();
RouteDiscoverResponse(); RouteDiscoverResponse();
@ -21,7 +21,7 @@ enum PackageTypes {
/** /**
Parse package from an `modem_message` event. Parse package from an `modem_message` event.
**/ **/
public static function fromEvent(params: Array<Dynamic>): Package { public static function fromEvent(params:Array<Dynamic>):Package {
var payload = params[4]; var payload = params[4];
return { return {
@ -36,7 +36,7 @@ enum PackageTypes {
/** /**
Create package that can be used as a response. Create package that can be used as a response.
**/ **/
public function createResponse(newData: Dynamic): Package { public function createResponse(newData:Dynamic):Package {
return { return {
toID: fromID, toID: fromID,
fromID: toID, fromID: toID,
@ -49,7 +49,7 @@ enum PackageTypes {
/** /**
Wrapper for `Net.instance.respondTo`. Wrapper for `Net.instance.respondTo`.
**/ **/
public function respond(data: Dynamic) { public function respond(data:Dynamic) {
Net.instance.respondTo(this,data); Net.instance.respondTo(this, data);
} }
} }

View File

@ -1,31 +0,0 @@
package kernel.peripherals;
class Item {
}
class Inventory {
public function size():Int {
}
public function list(): Map<Int,Item> {
}
public function getItemDetail(slot: Int): Item {
}
public function pushItems(toName: String, fromSlot: Int, ?limit:Int, toSlot: Int): Int {
}
public function pullItems(fromName: String, fromSlot: Int, ?limit:Int, ?toSlot: Int): Int {
}
}

View File

@ -11,20 +11,20 @@ class Modem {
public final addr:String; public final addr:String;
@:allow(kernel.peripherals) @:allow(kernel.peripherals)
private function new(nativePeripherals: cc.periphs.Modem.Modem,addr: String) { private function new(nativePeripherals:cc.periphs.Modem.Modem, addr:String) {
this.nativ = nativePeripherals; this.nativ = nativePeripherals;
this.addr = addr; this.addr = addr;
} }
public function open(chan: Int) { public function open(chan:Int) {
nativ.open(chan); nativ.open(chan);
} }
public function isOpen(chan: Int): Bool { public function isOpen(chan:Int):Bool {
return nativ.isOpen(chan); return nativ.isOpen(chan);
} }
public function close(chan: Int) { public function close(chan:Int) {
nativ.close(chan); nativ.close(chan);
} }
@ -32,32 +32,32 @@ class Modem {
nativ.closeAll(); nativ.closeAll();
} }
public function transmit(chan: Int,replyChan: Int,payload: Any) { public function transmit(chan:Int, replyChan:Int, payload:Any) {
nativ.transmit(chan,replyChan,payload); nativ.transmit(chan, replyChan, payload);
} }
public function isWireless(): Bool { public function isWireless():Bool {
return nativ.isWireless(); return nativ.isWireless();
} }
public function getNamesRemote():Array<String> { public function getNamesRemote():Array<String> {
if (isWireless()){ if (isWireless()) {
throw new Exception("'getNamesRemote' only works with wired modems"); throw new Exception("'getNamesRemote' only works with wired modems");
} }
return nativ.getNamesRemote().toArray(); return nativ.getNamesRemote().toArray();
} }
public function isPresentRemote(name: String): Bool { public function isPresentRemote(name:String):Bool {
if (isWireless()){ if (isWireless()) {
throw new Exception("'isPresentRemote' only works with wired modems"); throw new Exception("'isPresentRemote' only works with wired modems");
} }
return nativ.isPresentRemote(name); return nativ.isPresentRemote(name);
} }
public function getTypeRemote(name: String): String { public function getTypeRemote(name:String):String {
if (isWireless()){ if (isWireless()) {
throw new Exception("'getTypeRemote' only works with wired modems"); throw new Exception("'getTypeRemote' only works with wired modems");
} }
@ -65,7 +65,7 @@ class Modem {
} }
public function hasTypeRemote(name:String, type:String):Bool { public function hasTypeRemote(name:String, type:String):Bool {
if (isWireless()){ if (isWireless()) {
throw new Exception("'hasTypeRemote' only works with wired modems"); throw new Exception("'hasTypeRemote' only works with wired modems");
} }
@ -74,16 +74,16 @@ class Modem {
// return nativ.hasRemoteType(name,type); // return nativ.hasRemoteType(name,type);
} }
public function getMethodsRemote(name: String): Array<String> { public function getMethodsRemote(name:String):Array<String> {
if (isWireless()){ if (isWireless()) {
throw new Exception("'getMethodsRemote' only works with wired modems"); throw new Exception("'getMethodsRemote' only works with wired modems");
} }
return nativ.getMethodsRemote(name).toArray(); return nativ.getMethodsRemote(name).toArray();
} }
public function callRemote(remoteName: String, method:String):Dynamic { public function callRemote(remoteName:String, method:String):Dynamic {
if (isWireless()){ if (isWireless()) {
throw new Exception("'callRemote' only works with wired modems"); throw new Exception("'callRemote' only works with wired modems");
} }
@ -91,8 +91,8 @@ class Modem {
throw new haxe.exceptions.NotImplementedException(); throw new haxe.exceptions.NotImplementedException();
} }
public function getNameLocal(): String { public function getNameLocal():String {
if (isWireless()){ if (isWireless()) {
throw new Exception("'getNameLocal' only works with wired modems"); throw new Exception("'getNameLocal' only works with wired modems");
} }

View File

@ -18,42 +18,42 @@ class Peripheral {
/** /**
Get all connected screens. Get all connected screens.
**/ **/
public function getScreens(): Array<Screen> { public function getScreens():Array<Screen> {
var allScreens = cc.Peripheral.getNames().toArray().filter(s -> cc.Peripheral.getType(s) == "monitor"); var allScreens = cc.Peripheral.getNames().toArray().filter(s -> cc.Peripheral.getType(s) == "monitor");
return allScreens.map(s -> return new Screen((cc.Peripheral.wrap(s):Dynamic),s)); return allScreens.map(s -> return new Screen((cc.Peripheral.wrap(s) : Dynamic), s));
} }
public function getScreen(addr: String): Screen { public function getScreen(addr:String):Screen {
if (!getAllPeripheralsAddr().exists(item -> item == addr)){ if (!getAllPeripheralsAddr().exists(item -> item == addr)) {
return null; return null;
} }
return new Screen((cc.Peripheral.wrap(addr):Dynamic),addr); return new Screen((cc.Peripheral.wrap(addr) : Dynamic), addr);
} }
/** /**
Get all connected modems. Get all connected modems.
**/ **/
public function getModems(): Array<Modem> { public function getModems():Array<Modem> {
var allModems = cc.Peripheral.getNames().toArray().filter(s -> cc.Peripheral.getType(s) == "modem"); var allModems = cc.Peripheral.getNames().toArray().filter(s -> cc.Peripheral.getType(s) == "modem");
return allModems.map(s -> return new Modem((cc.Peripheral.wrap(s): Dynamic),s)); return allModems.map(s -> return new Modem((cc.Peripheral.wrap(s) : Dynamic), s));
} }
/** /**
Get all connected wireless modems. Get all connected wireless modems.
**/ **/
public function getWirelessModems(): Array<Modem> { public function getWirelessModems():Array<Modem> {
return getModems().filter(modem -> return modem.isWireless()); return getModems().filter(modem -> return modem.isWireless());
} }
/** /**
Get all connected wired modems. Get all connected wired modems.
**/ **/
public function getWiredModems(): Array<Modem> { public function getWiredModems():Array<Modem> {
return getModems().filter(modem -> return !modem.isWireless()); return getModems().filter(modem -> return !modem.isWireless());
} }
public function getAllPeripheralsAddr(): Array<String> { public function getAllPeripheralsAddr():Array<String> {
return cc.Peripheral.getNames().toArray(); return cc.Peripheral.getNames().toArray();
} }
} }

View File

@ -7,17 +7,16 @@ import lib.TermWriteable;
import util.Vec.Vec2; import util.Vec.Vec2;
import util.Color; import util.Color;
class Screen implements TermWriteable{ class Screen implements TermWriteable {
private final nativ:cc.periphs.Monitor.Monitor; private final nativ:cc.periphs.Monitor.Monitor;
private final addr:String; private final addr:String;
private final onResizeTrigger:SignalTrigger<Vec2<Int>>;
private final onResizeTrigger: SignalTrigger<Vec2<Int>>; public var onResize(default, null):Signal<Vec2<Int>>;
public var onResize(default,null):Signal<Vec2<Int>>;
@:allow(kernel.peripherals) @:allow(kernel.peripherals)
public function new(nativePeripherals: cc.periphs.Monitor.Monitor,addr: String) { public function new(nativePeripherals:cc.periphs.Monitor.Monitor, addr:String) {
this.onResizeTrigger = Signal.trigger(); this.onResizeTrigger = Signal.trigger();
this.onResize = onResizeTrigger.asSignal(); this.onResize = onResizeTrigger.asSignal();
@ -25,7 +24,7 @@ class Screen implements TermWriteable{
this.addr = addr; this.addr = addr;
KernelEvents.instance.onMonitorResize.handle(addr -> { KernelEvents.instance.onMonitorResize.handle(addr -> {
if (addr == this.addr){ if (addr == this.addr) {
onResizeTrigger.trigger(getSize()); onResizeTrigger.trigger(getSize());
} }
}); });
@ -33,45 +32,45 @@ class Screen implements TermWriteable{
setTextScale(0.5); setTextScale(0.5);
} }
public function getAddr(): String { public function getAddr():String {
return this.addr; return this.addr;
} }
public function getTextScale(): Float { public function getTextScale():Float {
return nativ.getTextScale(); return nativ.getTextScale();
} }
public function setTextScale(scale: Float) { public function setTextScale(scale:Float) {
nativ.setTextScale(scale); nativ.setTextScale(scale);
} }
public function write(text:String) { public function write(text:String) {
nativ.write(text); nativ.write(text);
} }
public function scroll(y:Int) { public function scroll(y:Int) {
nativ.scroll(y); nativ.scroll(y);
} }
public function getCursorPos():Vec2<Int> { public function getCursorPos():Vec2<Int> {
var rtn = nativ.getCursorPos(); var rtn = nativ.getCursorPos();
return { return {
x: rtn.x - 1, x: rtn.x - 1,
y: rtn.y - 1 y: rtn.y - 1
} }
} }
public function setCursorPos(x:Int, y:Int) { public function setCursorPos(x:Int, y:Int) {
nativ.setCursorPos(x + 1,y + 1); nativ.setCursorPos(x + 1, y + 1);
} }
public function getCursorBlink():Bool { public function getCursorBlink():Bool {
return nativ.getCursorBlink(); return nativ.getCursorBlink();
} }
public function setCursorBlink(blink:Bool) { public function setCursorBlink(blink:Bool) {
nativ.setCursorBlink(blink); nativ.setCursorBlink(blink);
} }
public function getSize():Vec2<Int> { public function getSize():Vec2<Int> {
// FIXME: this will not compile. Has to be changes upstream // FIXME: this will not compile. Has to be changes upstream
@ -83,28 +82,28 @@ class Screen implements TermWriteable{
} }
public function clear() { public function clear() {
nativ.clear(); nativ.clear();
} }
public function clearLine() { public function clearLine() {
nativ.clearLine(); nativ.clearLine();
} }
public function getTextColor():Color { public function getTextColor():Color {
return ColorConvert.ccToColor(nativ.getTextColor()); return ColorConvert.ccToColor(nativ.getTextColor());
} }
public function setTextColor(colour:Color) { public function setTextColor(colour:Color) {
nativ.setTextColor(ColorConvert.colorToCC(colour)); nativ.setTextColor(ColorConvert.colorToCC(colour));
} }
public function getBackgroundColor():Color { public function getBackgroundColor():Color {
return ColorConvert.ccToColor(nativ.getBackgroundColor()); return ColorConvert.ccToColor(nativ.getBackgroundColor());
} }
public function setBackgroundColor(color:Color) { public function setBackgroundColor(color:Color) {
nativ.setBackgroundColor(ColorConvert.colorToCC(color)); nativ.setBackgroundColor(ColorConvert.colorToCC(color));
} }
public function isColor():Bool { public function isColor():Bool {
return nativ.isColor(); return nativ.isColor();

View File

@ -13,17 +13,18 @@ import lib.TermWriteable;
} }
class TermBuffer implements TermWriteable { class TermBuffer implements TermWriteable {
/** /**
format [y][x]. First index is the line. Second index the char in the line. format [y][x]. First index is the line. Second index the char in the line.
**/ **/
private var screenBuffer: Array<Array<Pixel>>; private var screenBuffer:Array<Array<Pixel>>;
private var cursorPos: Vec2<Int> = {x: 0, y: 0};
private var currentTextColor: Color = White; private var cursorPos:Vec2<Int> = {x: 0, y: 0};
private var currentBgColor: Color = Black; private var currentTextColor:Color = White;
private var size: Vec2<Int> = {x: 51,y:19}; // Default size set to default size of the main terminal private var currentBgColor:Color = Black;
private var size:Vec2<Int> = {x: 51, y: 19}; // Default size set to default size of the main terminal
public var onResize(default, null):Signal<Vec2<Int>>;
public var onResize(default,null):Signal<Vec2<Int>>;
private final onResizeTrigger:SignalTrigger<Vec2<Int>>; private final onResizeTrigger:SignalTrigger<Vec2<Int>>;
public function new() { public function new() {
@ -32,8 +33,8 @@ class TermBuffer implements TermWriteable {
initScreenBuffer(size); initScreenBuffer(size);
} }
private function setSize(size: Vec2<Int>) { private function setSize(size:Vec2<Int>) {
if (this.size != size){ if (this.size != size) {
this.onResizeTrigger.trigger(size); this.onResizeTrigger.trigger(size);
} }
@ -41,15 +42,15 @@ class TermBuffer implements TermWriteable {
updateScreenBufferSize(size); updateScreenBufferSize(size);
} }
private function updateScreenBufferSize(size: Vec2<Int>) { private function updateScreenBufferSize(size:Vec2<Int>) {
// TODO // TODO
} }
private function initScreenBuffer(size: Vec2<Int>) { private function initScreenBuffer(size:Vec2<Int>) {
screenBuffer = new Array(); screenBuffer = new Array();
for (y in 0...size.y){ for (y in 0...size.y) {
screenBuffer[y] = new Array(); screenBuffer[y] = new Array();
for (x in 0...size.x){ for (x in 0...size.x) {
screenBuffer[y][x] = { screenBuffer[y][x] = {
char: " ", char: " ",
textColor: White, textColor: White,
@ -59,62 +60,64 @@ class TermBuffer implements TermWriteable {
} }
} }
private function copyBufferToTarget(target: TermWriteable) { private function copyBufferToTarget(target:TermWriteable) {
target.setCursorPos(0,0); target.setCursorPos(0, 0);
target.setBackgroundColor(Black); target.setBackgroundColor(Black);
target.setTextColor(White); target.setTextColor(White);
var tmpFgColor: Color = White; var tmpFgColor:Color = White;
var tmpBgColor: Color = Black; var tmpBgColor:Color = Black;
for (y => line in screenBuffer){ for (y => line in screenBuffer) {
for(x => pixel in line){ for (x => pixel in line) {
if (tmpFgColor != pixel.textColor){ if (tmpFgColor != pixel.textColor) {
tmpFgColor = pixel.textColor; tmpFgColor = pixel.textColor;
target.setTextColor(pixel.textColor); target.setTextColor(pixel.textColor);
} }
if (tmpBgColor != pixel.bg){ if (tmpBgColor != pixel.bg) {
tmpBgColor = pixel.bg; tmpBgColor = pixel.bg;
target.setBackgroundColor(pixel.bg); target.setBackgroundColor(pixel.bg);
} }
target.setCursorPos(x,y); target.setCursorPos(x, y);
target.write(pixel.char); target.write(pixel.char);
} }
} }
target.setCursorPos(cursorPos.x,cursorPos.y); target.setCursorPos(cursorPos.x, cursorPos.y);
target.setTextColor(currentTextColor); target.setTextColor(currentTextColor);
target.setBackgroundColor(currentBgColor); target.setBackgroundColor(currentBgColor);
} }
private function safeWriteScreenBuffer(pos: Vec2<Int>,char: String) { private function safeWriteScreenBuffer(pos:Vec2<Int>, char:String) {
if (screenBuffer.length > pos.y && screenBuffer[pos.y].length > pos.x){ if (screenBuffer.length > pos.y && screenBuffer[pos.y].length > pos.x) {
screenBuffer[pos.y][pos.x].char = char; screenBuffer[pos.y][pos.x].char = char;
screenBuffer[pos.y][pos.x].bg = currentBgColor; screenBuffer[pos.y][pos.x].bg = currentBgColor;
screenBuffer[pos.y][pos.x].textColor = currentTextColor; screenBuffer[pos.y][pos.x].textColor = currentTextColor;
} }
} }
// //
// TermWriteable functions // TermWriteable functions
// //
public function write(text:String) { public function write(text:String) {
for (i in 0...text.length){ for (i in 0...text.length) {
safeWriteScreenBuffer({x: cursorPos.x,y: cursorPos.y},text.charAt(i)); safeWriteScreenBuffer({x: cursorPos.x, y: cursorPos.y}, text.charAt(i));
cursorPos = {y: cursorPos.y,x: cursorPos.x + 1}; cursorPos = {y: cursorPos.y, x: cursorPos.x + 1};
} }
} }
public function scroll(y:Int) { public function scroll(y:Int) {
screenBuffer.unshift([for (i in 0...size.x) { screenBuffer.unshift([
char: " ", for (i in 0...size.x)
textColor: White, // TODO: maybe replace with current bg/text color. Check nativ implementation {
bg: Black char: " ",
}]); textColor: White, // TODO: maybe replace with current bg/text color. Check nativ implementation
bg: Black
}
]);
} }
public function getCursorPos():Vec2<Int> { public function getCursorPos():Vec2<Int> {
@ -145,8 +148,8 @@ class TermBuffer implements TermWriteable {
} }
public function clearLine() { public function clearLine() {
if (screenBuffer.length > cursorPos.y){ if (screenBuffer.length > cursorPos.y) {
screenBuffer[cursorPos.y] = [for(x in 0...size.x){textColor: White,char: " ",bg: Black}]; screenBuffer[cursorPos.y] = [for (x in 0...size.x) {textColor: White, char: " ", bg: Black}];
} }
} }

View File

@ -7,157 +7,157 @@ import util.Color;
import lib.TermWriteable; import lib.TermWriteable;
class VirtualTermWriter implements TermWriteable extends TermBuffer { class VirtualTermWriter implements TermWriteable extends TermBuffer {
private static final defaultSize:Vec2<Int> = {x: 50,y: 50}; private static final defaultSize:Vec2<Int> = {x: 50, y: 50};
private var target: TermWriteable; private var target:TermWriteable;
private var enabled:Bool = false; private var enabled:Bool = false;
private var onResizeLink: CallbackLink; private var onResizeLink:CallbackLink;
public function new(?target: TermWriteable) { public function new(?target:TermWriteable) {
setTarget(target); setTarget(target);
if (enabled){ if (enabled) {
enable(); enable();
} }
super(); super();
} }
public function enable() { public function enable() {
if (target != null){ if (target != null) {
enabled = true; enabled = true;
super.copyBufferToTarget(target); super.copyBufferToTarget(target);
} }
} }
public function disable() { public function disable() {
enabled = false; enabled = false;
} }
public inline function isEnabled(): Bool { public inline function isEnabled():Bool {
return enabled; return enabled;
} }
public function setTarget(newTarget: TermWriteable) { public function setTarget(newTarget:TermWriteable) {
if (newTarget != null){ if (newTarget != null) {
super.setSize(newTarget.getSize()); super.setSize(newTarget.getSize());
// Remove old target event listner // Remove old target event listner
if (onResizeLink != null){ if (onResizeLink != null) {
onResizeLink.cancel(); onResizeLink.cancel();
} }
// Add new target event listner // Add new target event listner
onResizeLink = newTarget.onResize.handle(newSize -> { onResizeLink = newTarget.onResize.handle(newSize -> {
setSuperSize(newSize); setSuperSize(newSize);
}); });
target = newTarget; target = newTarget;
} }
} }
private function setSuperSize(size: Vec2<Int>) { private function setSuperSize(size:Vec2<Int>) {
super.setSize(target.getSize()); super.setSize(target.getSize());
} }
// //
// TermWriteable functions. // TermWriteable functions.
// //
public override function write(text:String) { public override function write(text:String) {
if (isEnabled()){ if (isEnabled()) {
target.write(text); target.write(text);
} }
super.write(text); super.write(text);
} }
public override function scroll(y:Int) { public override function scroll(y:Int) {
if (isEnabled()){ if (isEnabled()) {
target.scroll(y); target.scroll(y);
} }
super.scroll(y); super.scroll(y);
} }
public override function getCursorPos():Vec2<Int> { public override function getCursorPos():Vec2<Int> {
if (isEnabled()){ if (isEnabled()) {
return target.getCursorPos(); return target.getCursorPos();
}else{ } else {
return super.getCursorPos(); return super.getCursorPos();
} }
} }
public override function setCursorPos(x:Int, y:Int) { public override function setCursorPos(x:Int, y:Int) {
if (isEnabled()){ if (isEnabled()) {
target.setCursorPos(x,y); target.setCursorPos(x, y);
} }
super.setCursorPos(x,y); super.setCursorPos(x, y);
} }
public override function getCursorBlink():Bool { public override function getCursorBlink():Bool {
throw new haxe.exceptions.NotImplementedException(); throw new haxe.exceptions.NotImplementedException();
} }
public override function setCursorBlink(blink:Bool) { public override function setCursorBlink(blink:Bool) {
// TODO // TODO
} }
public override function getSize():Vec2<Int> { public override function getSize():Vec2<Int> {
// TODO: make sense ? // TODO: make sense ?
if (target != null){ if (target != null) {
return target.getSize(); return target.getSize();
} }
return defaultSize; return defaultSize;
} }
public override function clear() { public override function clear() {
if (isEnabled()){ if (isEnabled()) {
target.clear(); target.clear();
} }
super.clear(); super.clear();
} }
public override function clearLine() { public override function clearLine() {
if (isEnabled()){ if (isEnabled()) {
target.clearLine(); target.clearLine();
} }
super.clearLine(); super.clearLine();
} }
public override function getTextColor():Color { public override function getTextColor():Color {
if (isEnabled()){ if (isEnabled()) {
return target.getTextColor(); return target.getTextColor();
} }
return super.getTextColor(); return super.getTextColor();
} }
public override function setTextColor(colour:Color) { public override function setTextColor(colour:Color) {
if (isEnabled()){ if (isEnabled()) {
target.setTextColor(colour); target.setTextColor(colour);
} }
super.setTextColor(colour); super.setTextColor(colour);
} }
public override function getBackgroundColor():Color { public override function getBackgroundColor():Color {
if (isEnabled()){ if (isEnabled()) {
return target.getBackgroundColor(); return target.getBackgroundColor();
} }
return super.getBackgroundColor(); return super.getBackgroundColor();
} }
public override function setBackgroundColor(color:Color) { public override function setBackgroundColor(color:Color) {
if (isEnabled()){ if (isEnabled()) {
target.setBackgroundColor(color); target.setBackgroundColor(color);
} }
super.setBackgroundColor(color); super.setBackgroundColor(color);
} }
public override function isColor():Bool { public override function isColor():Bool {
throw new haxe.exceptions.NotImplementedException(); throw new haxe.exceptions.NotImplementedException();

View File

@ -8,120 +8,118 @@ import util.Vec.Vec2;
import lib.TermWriteable; import lib.TermWriteable;
class WindowContext implements TermWriteable { class WindowContext implements TermWriteable {
private final writer:VirtualTermWriter; private final writer:VirtualTermWriter;
public var clickSignal(default,null):Signal<{button: ButtonType, pos: Vec2<Int>}>; public var clickSignal(default, null):Signal<{button:ButtonType, pos:Vec2<Int>}>;
public var keySignal(default,null):Signal<{keyCode: Int, isHeld: Bool}>; public var keySignal(default, null):Signal<{keyCode:Int, isHeld:Bool}>;
public var keyUpSignal(default,null):Signal<Int>; public var keyUpSignal(default, null):Signal<Int>;
public var mouseDragSignal(default,null):Signal<{button: ButtonType, pos: Vec2<Int>}>; public var mouseDragSignal(default, null):Signal<{button:ButtonType, pos:Vec2<Int>}>;
public var mouseScrollSignal(default,null):Signal<{dir: Int,pos: Vec2<Int>}>; public var mouseScrollSignal(default, null):Signal<{dir:Int, pos:Vec2<Int>}>;
public var mouseUpSignal(default,null):Signal<{button: ButtonType,pos: Vec2<Int>}>; public var mouseUpSignal(default, null):Signal<{button:ButtonType, pos:Vec2<Int>}>;
public var pasteSignal(default,null):Signal<String> ; public var pasteSignal(default, null):Signal<String>;
@:allow(kernel.ui.WindowManager) private final clickTrigger:SignalTrigger<{button: ButtonType, pos: Vec2<Int>}>; @:allow(kernel.ui.WindowManager) private final clickTrigger:SignalTrigger<{button:ButtonType, pos:Vec2<Int>}>;
@:allow(kernel.ui.WindowManager) private final keyTrigger:SignalTrigger<{keyCode: Int, isHeld: Bool}>; @:allow(kernel.ui.WindowManager) private final keyTrigger:SignalTrigger<{keyCode:Int, isHeld:Bool}>;
@:allow(kernel.ui.WindowManager) private final keyUpTrigger:SignalTrigger<Int>; @:allow(kernel.ui.WindowManager) private final keyUpTrigger:SignalTrigger<Int>;
@:allow(kernel.ui.WindowManager) private final mouseDragTrigger:SignalTrigger<{button: ButtonType, pos: Vec2<Int>}>; @:allow(kernel.ui.WindowManager) private final mouseDragTrigger:SignalTrigger<{button:ButtonType, pos:Vec2<Int>}>;
@:allow(kernel.ui.WindowManager) private final mouseScrollTrigger:SignalTrigger<{dir: Int,pos: Vec2<Int>}>; @:allow(kernel.ui.WindowManager) private final mouseScrollTrigger:SignalTrigger<{dir:Int, pos:Vec2<Int>}>;
@:allow(kernel.ui.WindowManager) private final mouseUpTrigger:SignalTrigger<{button: ButtonType,pos: Vec2<Int>}>; @:allow(kernel.ui.WindowManager) private final mouseUpTrigger:SignalTrigger<{button:ButtonType, pos:Vec2<Int>}>;
@:allow(kernel.ui.WindowManager) private final pasteTrigger:SignalTrigger<String>; @:allow(kernel.ui.WindowManager) private final pasteTrigger:SignalTrigger<String>;
public function new(writer:VirtualTermWriter) {
this.writer = writer;
this.onResize = writer.onResize;
public function new(writer: VirtualTermWriter) { this.clickTrigger = Signal.trigger();
this.writer = writer; this.keyTrigger = Signal.trigger();
this.onResize = writer.onResize; this.keyUpTrigger = Signal.trigger();
this.mouseDragTrigger = Signal.trigger();
this.mouseScrollTrigger = Signal.trigger();
this.mouseUpTrigger = Signal.trigger();
this.pasteTrigger = Signal.trigger();
this.clickTrigger = Signal.trigger(); this.clickSignal = clickTrigger.asSignal();
this.keyTrigger = Signal.trigger(); this.keySignal = keyTrigger.asSignal();
this.keyUpTrigger = Signal.trigger(); this.keyUpSignal = keyUpTrigger.asSignal();
this.mouseDragTrigger = Signal.trigger(); this.mouseDragSignal = mouseDragTrigger.asSignal();
this.mouseScrollTrigger = Signal.trigger(); this.mouseScrollSignal = mouseScrollTrigger.asSignal();
this.mouseUpTrigger = Signal.trigger(); this.mouseUpSignal = mouseUpTrigger.asSignal();
this.pasteTrigger = Signal.trigger(); this.pasteSignal = pasteTrigger.asSignal();
}
this.clickSignal = clickTrigger.asSignal(); public var onResize(default, null):Signal<Vec2<Int>>;
this.keySignal = keyTrigger.asSignal();
this.keyUpSignal = keyUpTrigger.asSignal();
this.mouseDragSignal = mouseDragTrigger.asSignal();
this.mouseScrollSignal = mouseScrollTrigger.asSignal();
this.mouseUpSignal = mouseUpTrigger.asSignal();
this.pasteSignal = pasteTrigger.asSignal();
} @:allow(kernel.ui)
private function setTarget(target:TermWriteable) {
writer.setTarget(target);
}
public var onResize(default, null):Signal<Vec2<Int>>; @:allow(kernel.ui)
private function enable() {
writer.enable();
}
@:allow(kernel.ui) @:allow(kernel.ui)
private function setTarget(target: TermWriteable) { private function disable() {
writer.setTarget(target); writer.disable();
} }
@:allow(kernel.ui) @:allow(kernel.ui)
private function enable() { private function isEnabled() {
writer.enable(); return writer.isEnabled();
} }
@:allow(kernel.ui)
private function disable() {
writer.disable();
}
@:allow(kernel.ui)
private function isEnabled() {
return writer.isEnabled();
}
public function write(text:String) { public function write(text:String) {
writer.write(text); writer.write(text);
} }
public function scroll(y:Int) { public function scroll(y:Int) {
writer.scroll(y); writer.scroll(y);
} }
public function getCursorPos():Vec2<Int> { public function getCursorPos():Vec2<Int> {
return writer.getCursorPos(); return writer.getCursorPos();
} }
public function setCursorPos(x:Int, y:Int) { public function setCursorPos(x:Int, y:Int) {
writer.setCursorPos(x,y); writer.setCursorPos(x, y);
} }
public function getCursorBlink():Bool { public function getCursorBlink():Bool {
return writer.getCursorBlink(); return writer.getCursorBlink();
} }
public function setCursorBlink(blink:Bool) { public function setCursorBlink(blink:Bool) {
writer.setCursorBlink(blink); writer.setCursorBlink(blink);
} }
public function getSize():Vec2<Int> { public function getSize():Vec2<Int> {
return writer.getSize(); return writer.getSize();
} }
public function clear() { public function clear() {
writer.clear(); writer.clear();
} }
public function clearLine() { public function clearLine() {
writer.clearLine(); writer.clearLine();
} }
public function getTextColor():Color { public function getTextColor():Color {
return writer.getTextColor(); return writer.getTextColor();
} }
public function setTextColor(colour:Color) { public function setTextColor(colour:Color) {
writer.setTextColor(colour); writer.setTextColor(colour);
} }
public function getBackgroundColor():Color { public function getBackgroundColor():Color {
return writer.getBackgroundColor(); return writer.getBackgroundColor();
} }
public function setBackgroundColor(color:Color) { public function setBackgroundColor(color:Color) {
writer.setBackgroundColor(color); writer.setBackgroundColor(color);
} }
public function isColor():Bool { public function isColor():Bool {
return writer.isColor(); return writer.isColor();

View File

@ -4,102 +4,98 @@ import lib.TermWriteable;
import kernel.peripherals.Peripherals.Peripheral; import kernel.peripherals.Peripherals.Peripheral;
class WindowManager { class WindowManager {
public static var instance:WindowManager; public static var instance:WindowManager;
@:allow(kernel.Init) @:allow(kernel.Init)
private function new() { private function new() {
KernelEvents.instance.onKey.handle(params -> {
if (currentMainContext != null) {
currentMainContext.keyTrigger.trigger(params);
}
});
KernelEvents.instance.onKey.handle(params ->{ KernelEvents.instance.onKeyUp.handle(keyCode -> {
if (currentMainContext != null){ if (currentMainContext != null) {
currentMainContext.keyTrigger.trigger(params); currentMainContext.keyUpTrigger.trigger(keyCode);
} }
}); });
KernelEvents.instance.onKeyUp.handle(keyCode -> { KernelEvents.instance.onMouseClick.handle(params -> {
if (currentMainContext != null){ if (currentMainContext != null) {
currentMainContext.keyUpTrigger.trigger(keyCode); currentMainContext.clickTrigger.trigger(params);
} }
}); });
KernelEvents.instance.onMouseClick.handle(params ->{ KernelEvents.instance.onMouseDrag.handle(params -> {
if (currentMainContext != null){ if (currentMainContext != null) {
currentMainContext.clickTrigger.trigger(params); currentMainContext.mouseDragTrigger.trigger(params);
} }
}); });
KernelEvents.instance.onMouseDrag.handle(params ->{ KernelEvents.instance.onMouseScroll.handle(params -> {
if (currentMainContext != null){ if (currentMainContext != null) {
currentMainContext.mouseDragTrigger.trigger(params); currentMainContext.mouseScrollTrigger.trigger(params);
} }
}); });
KernelEvents.instance.onMouseScroll.handle(params ->{ KernelEvents.instance.onMouseUp.handle(params -> {
if (currentMainContext != null){ if (currentMainContext != null) {
currentMainContext.mouseScrollTrigger.trigger(params); currentMainContext.mouseUpTrigger.trigger(params);
} }
}); });
KernelEvents.instance.onMouseUp.handle(params ->{ KernelEvents.instance.onPaste.handle(text -> {
if (currentMainContext != null){ if (currentMainContext != null) {
currentMainContext.mouseUpTrigger.trigger(params); currentMainContext.pasteTrigger.trigger(text);
} }
}); });
KernelEvents.instance.onPaste.handle(text->{ KernelEvents.instance.onMonitorTouch.handle(params -> {
if (currentMainContext != null){ // TODO
currentMainContext.pasteTrigger.trigger(text); });
} }
});
KernelEvents.instance.onMonitorTouch.handle(params ->{ private var currentMainContext:WindowContext;
// TODO private final allContexts:Array<WindowContext> = new Array();
}); private final outputMap:Map<String, WindowContext> = new Map();
}
private var currentMainContext:WindowContext; public function createNewContext():WindowContext {
private final allContexts:Array<WindowContext> = new Array(); var newContext = new WindowContext(new VirtualTermWriter());
private final outputMap:Map<String,WindowContext> = new Map();
public function createNewContext(): WindowContext { allContexts.push(newContext);
var newContext = new WindowContext(new VirtualTermWriter());
allContexts.push(newContext); // newContext.setTarget(MainTerm.instance);
newContext.enable();
currentMainContext = newContext;
// newContext.setTarget(MainTerm.instance); return newContext;
newContext.enable(); }
currentMainContext = newContext;
return newContext; public function getOutputs():Array<String> {
} var arr = Peripheral.instance.getScreens().map(screen -> return screen.getAddr());
arr.push("main");
return arr;
}
public function focusContextToOutput(context:WindowContext, output:String) {
var target:TermWriteable;
if (output == "main") {
target = MainTerm.instance;
} else {
target = Peripheral.instance.getScreen(output);
public function getOutputs(): Array<String> { if (target == null) {
var arr = Peripheral.instance.getScreens().map(screen -> return screen.getAddr()); // output target not found
arr.push("main"); return;
return arr; }
} }
public function focusContextToOutput(context: WindowContext,output: String) { if (outputMap.exists(output)) {
var target: TermWriteable; outputMap[output].disable();
if (output == "main"){ }
target = MainTerm.instance;
}else{
target = Peripheral.instance.getScreen(output);
if (target == null){ outputMap[output] = context;
// output target not found context.setTarget(target);
return; context.enable();
} }
}
if (outputMap.exists(output)){
outputMap[output].disable();
}
outputMap[output] = context;
context.setTarget(target);
context.enable();
}
} }

View File

@ -1,5 +1,5 @@
package lib; package lib;
interface IUserProgramm { interface IUserProgramm {
public function getName(): String; public function getName():String;
} }

View File

@ -1,6 +1,5 @@
package lib; package lib;
import util.Vec.Vec2;
import util.Color; import util.Color;
import lib.TermWriteable; import lib.TermWriteable;
@ -8,28 +7,28 @@ import lib.TermWriteable;
Helpfull class for writing onto a `TermWriteable`. Helpfull class for writing onto a `TermWriteable`.
**/ **/
class TermIO { class TermIO {
private var output: TermWriteable; private var output:TermWriteable;
public function new(output: TermWriteable) { public function new(output:TermWriteable) {
this.output = output; this.output = output;
output.clear(); output.clear();
output.setCursorPos(0,0); output.setCursorPos(0, 0);
} }
public function writeLn(text: String,?textColor: Color){ public function writeLn(text:String, ?textColor:Color) {
if (textColor != null){ if (textColor != null) {
output.setTextColor(textColor); output.setTextColor(textColor);
} }
var size = output.getSize(); var size = output.getSize();
for (i in 0...Math.floor(text.length / size.x) + 1){ for (i in 0...Math.floor(text.length / size.x) + 1) {
output.write(text.substr(i * size.x,size.x)); output.write(text.substr(i * size.x, size.x));
newLine(); newLine();
} }
if (textColor != null){ if (textColor != null) {
output.setTextColor(White); output.setTextColor(White);
} }
} }
@ -37,12 +36,11 @@ class TermIO {
private function newLine() { private function newLine() {
var cPos = output.getCursorPos(); var cPos = output.getCursorPos();
if (cPos.y == output.getSize().y){ if (cPos.y == output.getSize().y) {
output.scroll(1); output.scroll(1);
output.setCursorPos(0,cPos.y); output.setCursorPos(0, cPos.y);
}else{ } else {
output.setCursorPos(0,cPos.y + 1); output.setCursorPos(0, cPos.y + 1);
} }
} }
} }

View File

@ -6,34 +6,34 @@ import util.Color;
import util.Vec.Vec2; import util.Vec.Vec2;
/** /**
Interface describing a terminal. E.g. the main computer screen or a external screen. Interface describing a terminal. E.g. the main computer screen or a external screen.
**/ **/
interface TermWriteable { interface TermWriteable {
public var onResize(default, null):Signal<Vec2<Int>>;
public var onResize(default,null): Signal<Vec2<Int>>; public function write(text:String):Void;
public function scroll(y:Int):Void;
public function write(text: String): Void; /**
public function scroll(y: Int): Void; Even though CC is 1 based we use a 0 based index.
**/
public function getCursorPos():Vec2<Int>;
/** /**
Even though CC is 1 based we use a 0 based index. Even though CC is 1 based we use a 0 based index.
**/ **/
public function getCursorPos(): Vec2<Int>; public function setCursorPos(x:Int, y:Int):Void;
/** public function getCursorBlink():Bool;
Even though CC is 1 based we use a 0 based index. public function setCursorBlink(blink:Bool):Void;
**/ public function getSize():Vec2<Int>;
public function setCursorPos(x: Int, y: Int):Void; public function clear():Void;
public function getCursorBlink(): Bool; public function clearLine():Void;
public function setCursorBlink(blink: Bool):Void; public function getTextColor():Color;
public function getSize(): Vec2<Int>; public function setTextColor(colour:Color):Void;
public function clear(): Void; public function getBackgroundColor():Color;
public function clearLine(): Void; public function setBackgroundColor(color:Color):Void;
public function getTextColor():Color; public function isColor():Bool;
public function setTextColor(colour: Color):Void; // setPaletteColor(...)
public function getBackgroundColor(): Color; // getPaletteColor(colour)
public function setBackgroundColor(color: Color):Void;
public function isColor(): Bool;
// setPaletteColor(...)
// getPaletteColor(colour)
} }

View File

@ -8,32 +8,32 @@ abstract Canvas(Array<Array<Pixel>>) to Array<Array<Pixel>> {
this = [[]]; this = [[]];
} }
public inline function set(i:Vec2<Int>,pixel:Pixel) { public inline function set(i:Vec2<Int>, pixel:Pixel) {
if (this[i.y] == null){ if (this[i.y] == null) {
this[i.y] = []; this[i.y] = [];
} }
this[i.y][i.x] = pixel; this[i.y][i.x] = pixel;
} }
public inline function get(i:Vec2<Int>): Pixel { public inline function get(i:Vec2<Int>):Pixel {
return this[i.y][i.x]; return this[i.y][i.x];
} }
public function keyValueIterator(): KeyValueIterator<Vec2<Int>,Pixel>{ public function keyValueIterator():KeyValueIterator<Vec2<Int>, Pixel> {
return new CanvasKeyValueIterator(this); return new CanvasKeyValueIterator(this);
} }
public function combine(other: Canvas,offset: Vec2<Int>) { public function combine(other:Canvas, offset:Vec2<Int>) {
for (key => value in other) { for (key => value in other) {
if (value == null){ if (value == null) {
continue; continue;
} }
var y = offset.y + key.y; var y = offset.y + key.y;
var x = offset.x + key.x; var x = offset.x + key.x;
if (this[y] == null){ if (this[y] == null) {
this[y] = []; this[y] = [];
} }
@ -41,14 +41,14 @@ abstract Canvas(Array<Array<Pixel>>) to Array<Array<Pixel>> {
} }
} }
public function hight(): Int { public function hight():Int {
return this.length; return this.length;
} }
public function maxWidth() { public function maxWidth() {
var max = 0; var max = 0;
for (i in 0...this.length){ for (i in 0...this.length) {
if (this[i].length > max){ if (this[i].length > max) {
max = this[i].length; max = this[i].length;
} }
} }
@ -57,28 +57,28 @@ abstract Canvas(Array<Array<Pixel>>) to Array<Array<Pixel>> {
} }
} }
class CanvasKeyValueIterator{ class CanvasKeyValueIterator {
private final canvas:Array<Array<Pixel>>; private final canvas:Array<Array<Pixel>>;
private var index:Vec2<Int> = {x: 0,y: 0}; private var index:Vec2<Int> = {x: 0, y: 0};
@:allow(lib.ui.Canvas) @:allow(lib.ui.Canvas)
private function new(canvas: Array<Array<Pixel>>) { private function new(canvas:Array<Array<Pixel>>) {
this.canvas = canvas; this.canvas = canvas;
} }
public function hasNext():Bool{ public function hasNext():Bool {
return index.y < canvas.length && index.x <= canvas[index.y].length; return index.y < canvas.length && index.x <= canvas[index.y].length;
} }
public function next():{key:Vec2<Int>, value:Pixel}{ public function next():{key:Vec2<Int>, value:Pixel} {
var oldIndex: Vec2<Int> = this.index; var oldIndex:Vec2<Int> = this.index;
if (index.x >= canvas[index.y].length){ if (index.x >= canvas[index.y].length) {
// Goto next line // Goto next line
index = {x:0,y: index.y + 1}; index = {x: 0, y: index.y + 1};
}else{ } else {
// Goto next pixel in line // Goto next pixel in line
index = {x:index.x + 1,y: index.y}; index = {x: index.x + 1, y: index.y};
} }
return { return {

View File

@ -1,9 +1,10 @@
package lib.ui; package lib.ui;
using tink.CoreApi; using tink.CoreApi;
import util.Vec.Vec2; import util.Vec.Vec2;
interface IElement { interface IElement {
public function render(bounds: Vec2<Int>): Canvas; public function render(bounds:Vec2<Int>):Canvas;
public var changed(default, null):Signal<Noise>; public var changed(default, null):Signal<Noise>;
} }

View File

@ -3,26 +3,26 @@ package lib.ui;
using tink.CoreApi; using tink.CoreApi;
class Observable<T> { class Observable<T> {
private var value: T; private var value:T;
private var callbacks: CallbackList<T> = new CallbackList(true); private var callbacks:CallbackList<T> = new CallbackList(true);
public function new(value: T) { public function new(value:T) {
this.value = value; this.value = value;
} }
public function set(value: T) { public function set(value:T) {
if (value != this.value){ if (value != this.value) {
this.value = value; this.value = value;
callbacks.invoke(value); callbacks.invoke(value);
} }
} }
public function get(): T { public function get():T {
return value; return value;
} }
public function subscribe(callback: Callback<T>):CallbackLink { public function subscribe(callback:Callback<T>):CallbackLink {
callback.invoke(value); callback.invoke(value);
return callbacks.add(callback); return callbacks.add(callback);
} }
} }

View File

@ -9,11 +9,11 @@ class ReactiveUI {
private final context:WindowContext; private final context:WindowContext;
private final children:Array<IElement>; private final children:Array<IElement>;
public function new(context: WindowContext,children: Array<IElement>) { public function new(context:WindowContext, children:Array<IElement>) {
this.context = context; this.context = context;
this.children = children; this.children = children;
for(child in children){ for (child in children) {
child.changed.handle(v -> { child.changed.handle(v -> {
render(); render();
}); });
@ -23,37 +23,36 @@ class ReactiveUI {
public function render() { public function render() {
var size = context.getSize(); var size = context.getSize();
var screen = renderChildren(children,size); var screen = renderChildren(children, size);
writeToContext(screen); writeToContext(screen);
} }
private function writeToContext(screen: Canvas) { private function writeToContext(screen:Canvas) {
var currentBg: Color = Black; var currentBg:Color = Black;
var currentFg: Color = White; var currentFg:Color = White;
var currentLine = 0; var currentLine = 0;
context.setBackgroundColor(currentBg); context.setBackgroundColor(currentBg);
context.setTextColor(currentFg); context.setTextColor(currentFg);
context.setCursorPos(0,0); context.setCursorPos(0, 0);
for (key => pixel in screen) { for (key => pixel in screen) {
if (key.y != currentLine) {
if (key.y != currentLine){
currentLine = key.y; currentLine = key.y;
context.setCursorPos(key.x,key.y); context.setCursorPos(key.x, key.y);
} }
if (pixel == null){ if (pixel == null) {
context.write(' '); context.write(' ');
}else{ } else {
if (pixel.bg != currentBg){ if (pixel.bg != currentBg) {
context.setBackgroundColor(pixel.bg); context.setBackgroundColor(pixel.bg);
currentBg = pixel.bg; currentBg = pixel.bg;
} }
if (pixel.textColor != currentFg){ if (pixel.textColor != currentFg) {
context.setTextColor(pixel.textColor); context.setTextColor(pixel.textColor);
currentFg = pixel.textColor; currentFg = pixel.textColor;
} }
@ -63,13 +62,13 @@ class ReactiveUI {
} }
} }
public static function renderChildren(children: Array<IElement>,bounds: Vec2<Int>): Canvas { public static function renderChildren(children:Array<IElement>, bounds:Vec2<Int>):Canvas {
var rtn: Canvas = new Canvas(); var rtn:Canvas = new Canvas();
var writePoint: Vec2<Int> = {x: 0,y: 0}; var writePoint:Vec2<Int> = {x: 0, y: 0};
for (child in children) { for (child in children) {
if (bounds.y - writePoint.y <= 0){ if (bounds.y - writePoint.y <= 0) {
// No more space to render children // No more space to render children
Log.debug("No more space"); Log.debug("No more space");
break; break;
@ -80,9 +79,9 @@ class ReactiveUI {
y: bounds.y - writePoint.y y: bounds.y - writePoint.y
}); });
rtn.combine(childRender,writePoint); rtn.combine(childRender, writePoint);
writePoint = {x: 0,y: writePoint.y + childRender.hight() }; writePoint = {x: 0, y: writePoint.y + childRender.hight()};
} }
return rtn; return rtn;

View File

@ -7,41 +7,41 @@ import util.Vec.Vec2;
import util.MathI; import util.MathI;
class TextElement implements IElement { class TextElement implements IElement {
public var changed(default, null):Signal<Noise>; public var changed(default, null):Signal<Noise>;
private var changedTrigger:SignalTrigger<Noise>;
private final text: Observable<String>; private var changedTrigger:SignalTrigger<Noise>;
private final bg:Color;
private final fg:Color;
public function new(text: Observable<String>,?background: Color = Black,?textColor: Color = White) { private final text:Observable<String>;
private final bg:Color;
private final fg:Color;
setupTrigger(); public function new(text:Observable<String>, ?background:Color = Black, ?textColor:Color = White) {
setupTrigger();
this.text = text; this.text = text;
this.bg = background; this.bg = background;
this.fg = textColor; this.fg = textColor;
this.text.subscribe(value -> { this.text.subscribe(value -> {
this.changedTrigger.trigger(null); this.changedTrigger.trigger(null);
}); });
} }
private function setupTrigger() { private function setupTrigger() {
changedTrigger = Signal.trigger(); changedTrigger = Signal.trigger();
changed = changedTrigger.asSignal(); changed = changedTrigger.asSignal();
} }
public function render(bounds: Vec2<Int>):Canvas { public function render(bounds:Vec2<Int>):Canvas {
var rtn = new Canvas(); var rtn = new Canvas();
for (i in 0...MathI.min(Math.floor(text.get().length / bounds.x) + 1,bounds.y)){ for (i in 0...MathI.min(Math.floor(text.get().length / bounds.x) + 1, bounds.y)) {
var line = (text.get().substr(i * bounds.x,bounds.x)); var line = (text.get().substr(i * bounds.x, bounds.x));
for (char in 0...line.length) { for (char in 0...line.length) {
rtn.set({x: char,y: i},{textColor: fg,char: line.charAt(char),bg: bg}); rtn.set({x: char, y: i}, {textColor: fg, char: line.charAt(char), bg: bg});
} }
} }
return rtn; return rtn;
} }
} }

View File

@ -9,35 +9,34 @@ class BuildInfo {
**/ **/
public static macro function getGitCommitHash():haxe.macro.Expr.ExprOf<String> { public static macro function getGitCommitHash():haxe.macro.Expr.ExprOf<String> {
#if !display #if !display
var process = new sys.io.Process('git', ['rev-parse', 'HEAD']); var process = new sys.io.Process('git', ['rev-parse', 'HEAD']);
if (process.exitCode() != 0) { if (process.exitCode() != 0) {
var message = process.stderr.readAll().toString(); var message = process.stderr.readAll().toString();
var pos = haxe.macro.Context.currentPos(); var pos = haxe.macro.Context.currentPos();
haxe.macro.Context.error("Cannot execute `git rev-parse HEAD`. " + message, pos); haxe.macro.Context.error("Cannot execute `git rev-parse HEAD`. " + message, pos);
} }
// read the output of the process // read the output of the process
var commitHash:String = process.stdout.readLine(); var commitHash:String = process.stdout.readLine();
// Generates a string expression // Generates a string expression
return macro $v{commitHash}; return macro $v{commitHash};
#else #else
// `#if display` is used for code completion. In this case returning an // `#if display` is used for code completion. In this case returning an
// empty string is good enough; We don't want to call git on every hint. // empty string is good enough; We don't want to call git on every hint.
var commitHash:String = ""; var commitHash:String = "";
return macro $v{commitHash}; return macro $v{commitHash};
#end #end
} }
/** /**
Get the time the file was build. Get the time the file was build.
**/ **/
public static macro function buildTime(): haxe.macro.Expr.ExprOf<Int> { public static macro function buildTime():haxe.macro.Expr.ExprOf<Int> {
#if !display #if !display
return macro $v{Math.floor(Date.now().getTime())}; return macro $v{Math.floor(Date.now().getTime())};
#else #else
return macro $v{0}; return macro $v{0};
#end #end
} }
} }

View File

@ -25,7 +25,7 @@ enum Color {
} }
class ColorConvert { class ColorConvert {
public static function colorToCC(color: Color): cc.Colors.Color { public static function colorToCC(color:Color):cc.Colors.Color {
switch color { switch color {
case White: case White:
return Colors.white; return Colors.white;
@ -66,7 +66,7 @@ class ColorConvert {
}; };
} }
public static function ccToColor(color: cc.Colors.Color): Color { public static function ccToColor(color:cc.Colors.Color):Color {
switch color { switch color {
case 0: case 0:
return White; return White;

View File

@ -16,8 +16,8 @@ class Debug {
} }
#if webconsole #if webconsole
public static function printWeb(msg: String) { public static function printWeb(msg:String) {
HTTP.post("http://127.0.0.1:8080/",msg); HTTP.post("http://127.0.0.1:8080/", msg);
} }
#end #end
} }

View File

@ -10,7 +10,7 @@ class EventBusListner {
private final eventName:String; private final eventName:String;
@:allow(util.EventBus) @:allow(util.EventBus)
private function new(link: CallbackLink,eventName: String) { private function new(link:CallbackLink, eventName:String) {
this.link = link; this.link = link;
this.eventName = eventName; this.eventName = eventName;
} }
@ -19,43 +19,40 @@ class EventBusListner {
/** /**
Generic event handler. Generic event handler.
**/ **/
class EventBus<T>{ class EventBus<T> {
private var listner: Map<String,SignalTrigger<T>> = new Map(); private var listner:Map<String, SignalTrigger<T>> = new Map();
public function new() { public function new() {}
} public function on(eventName:String, callback:Callback<T>):EventBusListner {
if (!listner.exists(eventName)) {
public function on(eventName: String, callback: Callback<T>):EventBusListner{
if (!listner.exists(eventName)){
listner[eventName] = Signal.trigger(); listner[eventName] = Signal.trigger();
} }
var link = listner[eventName].asSignal().handle(callback); var link = listner[eventName].asSignal().handle(callback);
return new EventBusListner(link,eventName); return new EventBusListner(link, eventName);
} }
public function once(eventName: String,callback: Callback<T>):EventBusListner { public function once(eventName:String, callback:Callback<T>):EventBusListner {
if (!listner.exists(eventName)){ if (!listner.exists(eventName)) {
listner[eventName] = Signal.trigger(); listner[eventName] = Signal.trigger();
} }
var link = listner[eventName].asSignal().handle(callback); var link = listner[eventName].asSignal().handle(callback);
return new EventBusListner(link,eventName); return new EventBusListner(link, eventName);
} }
public function emit(eventName: String, data: T) { public function emit(eventName:String, data:T) {
if (listner.exists(eventName)){ if (listner.exists(eventName)) {
var trigger = listner[eventName]; var trigger = listner[eventName];
trigger.trigger(data); trigger.trigger(data);
} }
} }
public function removeListner(id: EventBusListner) { public function removeListner(id:EventBusListner) {
if (!listner.exists(id.eventName)) { if (!listner.exists(id.eventName)) {
return; return;
} }
id.link.cancel(); id.link.cancel();
} }
} }

View File

@ -7,16 +7,16 @@ class LambdaExtender {
Returns the first element if there are exectly one element present. Returns the first element if there are exectly one element present.
Throws exception if not. Throws exception if not.
**/ **/
static public function single<T>(it : Iterable<T>): T { static public function single<T>(it:Iterable<T>):T {
var elem: T = null; var elem:T = null;
for (t in it) { for (t in it) {
if (elem != null){ if (elem != null) {
throw new Exception("Multiple elements found"); throw new Exception("Multiple elements found");
} }
elem = t; elem = t;
} }
if (elem == null){ if (elem == null) {
throw new Exception("No element found"); throw new Exception("No element found");
} }
@ -26,16 +26,16 @@ class LambdaExtender {
/** /**
Like `single` but when no element was found return the default value. Like `single` but when no element was found return the default value.
**/ **/
static public function singleOrDefault<T>(it : Iterable<T>, defaultValue: T): T { static public function singleOrDefault<T>(it:Iterable<T>, defaultValue:T):T {
var elem: T = null; var elem:T = null;
for (t in it) { for (t in it) {
if (elem != null){ if (elem != null) {
throw new Exception("Multiple elements found"); throw new Exception("Multiple elements found");
} }
elem = t; elem = t;
} }
if (elem == null){ if (elem == null) {
return defaultValue; return defaultValue;
} }
@ -46,7 +46,7 @@ class LambdaExtender {
Returns the first element. Returns the first element.
Throws execption if no first element found. Throws execption if no first element found.
**/ **/
static public function first<T>(it : Iterable<T>): T { static public function first<T>(it:Iterable<T>):T {
for (t in it) { for (t in it) {
return t; return t;
} }
@ -57,10 +57,10 @@ class LambdaExtender {
/** /**
Like `first` only if no first element was found it returns the defalt value. Like `first` only if no first element was found it returns the defalt value.
**/ **/
static public function firstOrDefault<T>(it : Iterable<T>, defaultValue: T): T { static public function firstOrDefault<T>(it:Iterable<T>, defaultValue:T):T {
var iter = it.iterator(); var iter = it.iterator();
if (iter.hasNext()){ if (iter.hasNext()) {
return iter.next(); return iter.next();
} }

View File

@ -1,19 +1,19 @@
package util; package util;
class MathI { class MathI {
public static function max(a: Int, b:Int): Int { public static function max(a:Int, b:Int):Int {
if (a > b){ if (a > b) {
return a; return a;
}else{ } else {
return b; return b;
} }
} }
public static function min(a: Int,b:Int): Int { public static function min(a:Int, b:Int):Int {
if (a < b){ if (a < b) {
return a; return a;
}else{ } else {
return b; return b;
} }
} }
} }

View File

@ -6,35 +6,34 @@ import haxe.Exception;
JS-like promise class. JS-like promise class.
**/ **/
class Promise<T> { class Promise<T> {
private var thenCB: T->Void; private var thenCB:T->Void;
private var errorCB: Exception -> Void; private var errorCB:Exception->Void;
public function then(cb: (data: T)->Void): Promise<T> { public function then(cb:(data:T) -> Void):Promise<T> {
thenCB = cb; thenCB = cb;
return this; return this;
} }
public function error(cb: (err: Exception)->Void) { public function error(cb:(err:Exception) -> Void) {
errorCB = cb; errorCB = cb;
} }
public function new(func:(resolve:(T)->Void,reject:(Exception)->Void)->Void) { public function new(func:(resolve:(T) -> Void, reject:(Exception) -> Void)->Void) {
try { try {
func(data -> { func(data -> {
if (thenCB != null){ if (thenCB != null) {
thenCB(data); thenCB(data);
} }
},e -> { }, e -> {
if (errorCB != null){ if (errorCB != null) {
errorCB(e); errorCB(e);
} }
}); });
}catch(e:Exception){ } catch (e:Exception) {
if (errorCB != null){ if (errorCB != null) {
errorCB(e); errorCB(e);
} }
} }
} }
} }

View File

@ -1,13 +1,12 @@
package util; package util;
@:structInit class Vec2<T> { @:structInit class Vec2<T> {
public final x:T; public final x:T;
public final y:T; public final y:T;
} }
@:structInit class Vec3<T> { @:structInit class Vec3<T> {
public final x:T; public final x:T;
public final y:T; public final y:T;
public final z:T; public final z:T;
} }