format
This commit is contained in:
parent
f21e49c520
commit
0ad907f74a
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,12 +22,11 @@ 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);
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ class MainTerm implements TermWriteable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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 {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,15 +32,15 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +61,7 @@ class Screen implements TermWriteable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
@ -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([
|
||||||
|
for (i in 0...size.x)
|
||||||
|
{
|
||||||
char: " ",
|
char: " ",
|
||||||
textColor: White, // TODO: maybe replace with current bg/text color. Check nativ implementation
|
textColor: White, // TODO: maybe replace with current bg/text color. Check nativ implementation
|
||||||
bg: Black
|
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}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,16 +7,16 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function enable() {
|
public function enable() {
|
||||||
if (target != null){
|
if (target != null) {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
super.copyBufferToTarget(target);
|
super.copyBufferToTarget(target);
|
||||||
}
|
}
|
||||||
@ -34,16 +34,16 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setSuperSize(size: Vec2<Int>) {
|
private function setSuperSize(size:Vec2<Int>) {
|
||||||
super.setSize(target.getSize());
|
super.setSize(target.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,26 +72,26 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
@ -104,7 +104,7 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override function clear() {
|
public override function clear() {
|
||||||
if (isEnabled()){
|
if (isEnabled()) {
|
||||||
target.clear();
|
target.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override function clearLine() {
|
public override function clearLine() {
|
||||||
if (isEnabled()){
|
if (isEnabled()) {
|
||||||
target.clearLine();
|
target.clearLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override function getTextColor():Color {
|
public override function getTextColor():Color {
|
||||||
if (isEnabled()){
|
if (isEnabled()) {
|
||||||
return target.getTextColor();
|
return target.getTextColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override function setTextColor(colour:Color) {
|
public override function setTextColor(colour:Color) {
|
||||||
if (isEnabled()){
|
if (isEnabled()) {
|
||||||
target.setTextColor(colour);
|
target.setTextColor(colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override function getBackgroundColor():Color {
|
public override function getBackgroundColor():Color {
|
||||||
if (isEnabled()){
|
if (isEnabled()) {
|
||||||
return target.getBackgroundColor();
|
return target.getBackgroundColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ class VirtualTermWriter implements TermWriteable extends TermBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override function setBackgroundColor(color:Color) {
|
public override function setBackgroundColor(color:Color) {
|
||||||
if (isEnabled()){
|
if (isEnabled()) {
|
||||||
target.setBackgroundColor(color);
|
target.setBackgroundColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,24 +10,23 @@ 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) {
|
||||||
public function new(writer: VirtualTermWriter) {
|
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
this.onResize = writer.onResize;
|
this.onResize = writer.onResize;
|
||||||
|
|
||||||
@ -46,13 +45,12 @@ class WindowContext implements TermWriteable {
|
|||||||
this.mouseScrollSignal = mouseScrollTrigger.asSignal();
|
this.mouseScrollSignal = mouseScrollTrigger.asSignal();
|
||||||
this.mouseUpSignal = mouseUpTrigger.asSignal();
|
this.mouseUpSignal = mouseUpTrigger.asSignal();
|
||||||
this.pasteSignal = pasteTrigger.asSignal();
|
this.pasteSignal = pasteTrigger.asSignal();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var onResize(default, null):Signal<Vec2<Int>>;
|
public var onResize(default, null):Signal<Vec2<Int>>;
|
||||||
|
|
||||||
@:allow(kernel.ui)
|
@:allow(kernel.ui)
|
||||||
private function setTarget(target: TermWriteable) {
|
private function setTarget(target:TermWriteable) {
|
||||||
writer.setTarget(target);
|
writer.setTarget(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +82,7 @@ class WindowContext implements TermWriteable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
@ -8,59 +8,58 @@ class WindowManager {
|
|||||||
|
|
||||||
@:allow(kernel.Init)
|
@:allow(kernel.Init)
|
||||||
private function new() {
|
private function new() {
|
||||||
|
KernelEvents.instance.onKey.handle(params -> {
|
||||||
KernelEvents.instance.onKey.handle(params ->{
|
if (currentMainContext != null) {
|
||||||
if (currentMainContext != null){
|
|
||||||
currentMainContext.keyTrigger.trigger(params);
|
currentMainContext.keyTrigger.trigger(params);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
KernelEvents.instance.onKeyUp.handle(keyCode -> {
|
KernelEvents.instance.onKeyUp.handle(keyCode -> {
|
||||||
if (currentMainContext != null){
|
if (currentMainContext != null) {
|
||||||
currentMainContext.keyUpTrigger.trigger(keyCode);
|
currentMainContext.keyUpTrigger.trigger(keyCode);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
KernelEvents.instance.onMouseClick.handle(params ->{
|
KernelEvents.instance.onMouseClick.handle(params -> {
|
||||||
if (currentMainContext != null){
|
if (currentMainContext != null) {
|
||||||
currentMainContext.clickTrigger.trigger(params);
|
currentMainContext.clickTrigger.trigger(params);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
KernelEvents.instance.onMouseDrag.handle(params ->{
|
KernelEvents.instance.onMouseDrag.handle(params -> {
|
||||||
if (currentMainContext != null){
|
if (currentMainContext != null) {
|
||||||
currentMainContext.mouseDragTrigger.trigger(params);
|
currentMainContext.mouseDragTrigger.trigger(params);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
KernelEvents.instance.onMouseScroll.handle(params ->{
|
KernelEvents.instance.onMouseScroll.handle(params -> {
|
||||||
if (currentMainContext != null){
|
if (currentMainContext != null) {
|
||||||
currentMainContext.mouseScrollTrigger.trigger(params);
|
currentMainContext.mouseScrollTrigger.trigger(params);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
KernelEvents.instance.onMouseUp.handle(params ->{
|
KernelEvents.instance.onMouseUp.handle(params -> {
|
||||||
if (currentMainContext != null){
|
if (currentMainContext != null) {
|
||||||
currentMainContext.mouseUpTrigger.trigger(params);
|
currentMainContext.mouseUpTrigger.trigger(params);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
KernelEvents.instance.onPaste.handle(text->{
|
KernelEvents.instance.onPaste.handle(text -> {
|
||||||
if (currentMainContext != null){
|
if (currentMainContext != null) {
|
||||||
currentMainContext.pasteTrigger.trigger(text);
|
currentMainContext.pasteTrigger.trigger(text);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
KernelEvents.instance.onMonitorTouch.handle(params ->{
|
KernelEvents.instance.onMonitorTouch.handle(params -> {
|
||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private var currentMainContext:WindowContext;
|
private var currentMainContext:WindowContext;
|
||||||
private final allContexts:Array<WindowContext> = new Array();
|
private final allContexts:Array<WindowContext> = new Array();
|
||||||
private final outputMap:Map<String,WindowContext> = new Map();
|
private final outputMap:Map<String, WindowContext> = new Map();
|
||||||
|
|
||||||
public function createNewContext(): WindowContext {
|
public function createNewContext():WindowContext {
|
||||||
var newContext = new WindowContext(new VirtualTermWriter());
|
var newContext = new WindowContext(new VirtualTermWriter());
|
||||||
|
|
||||||
allContexts.push(newContext);
|
allContexts.push(newContext);
|
||||||
@ -72,32 +71,29 @@ class WindowManager {
|
|||||||
return newContext;
|
return newContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getOutputs():Array<String> {
|
||||||
public function getOutputs(): Array<String> {
|
|
||||||
var arr = Peripheral.instance.getScreens().map(screen -> return screen.getAddr());
|
var arr = Peripheral.instance.getScreens().map(screen -> return screen.getAddr());
|
||||||
arr.push("main");
|
arr.push("main");
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function focusContextToOutput(context: WindowContext,output: String) {
|
public function focusContextToOutput(context:WindowContext, output:String) {
|
||||||
var target: TermWriteable;
|
var target:TermWriteable;
|
||||||
if (output == "main"){
|
if (output == "main") {
|
||||||
target = MainTerm.instance;
|
target = MainTerm.instance;
|
||||||
}else{
|
} else {
|
||||||
target = Peripheral.instance.getScreen(output);
|
target = Peripheral.instance.getScreen(output);
|
||||||
|
|
||||||
if (target == null){
|
if (target == null) {
|
||||||
// output target not found
|
// output target not found
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (outputMap.exists(output)) {
|
||||||
if (outputMap.exists(output)){
|
|
||||||
outputMap[output].disable();
|
outputMap[output].disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
outputMap[output] = context;
|
outputMap[output] = context;
|
||||||
context.setTarget(target);
|
context.setTarget(target);
|
||||||
context.enable();
|
context.enable();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package lib;
|
package lib;
|
||||||
|
|
||||||
interface IUserProgramm {
|
interface IUserProgramm {
|
||||||
public function getName(): String;
|
public function getName():String;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,31 +9,31 @@ 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.
|
Even though CC is 1 based we use a 0 based index.
|
||||||
**/
|
**/
|
||||||
public function getCursorPos(): Vec2<Int>;
|
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 setCursorPos(x: Int, y: Int):Void;
|
public function setCursorPos(x:Int, y:Int):Void;
|
||||||
public function getCursorBlink(): Bool;
|
|
||||||
public function setCursorBlink(blink: Bool):Void;
|
public function getCursorBlink():Bool;
|
||||||
public function getSize(): Vec2<Int>;
|
public function setCursorBlink(blink:Bool):Void;
|
||||||
public function clear(): Void;
|
public function getSize():Vec2<Int>;
|
||||||
public function clearLine(): Void;
|
public function clear():Void;
|
||||||
|
public function clearLine():Void;
|
||||||
public function getTextColor():Color;
|
public function getTextColor():Color;
|
||||||
public function setTextColor(colour: Color):Void;
|
public function setTextColor(colour:Color):Void;
|
||||||
public function getBackgroundColor(): Color;
|
public function getBackgroundColor():Color;
|
||||||
public function setBackgroundColor(color: Color):Void;
|
public function setBackgroundColor(color:Color):Void;
|
||||||
public function isColor(): Bool;
|
public function isColor():Bool;
|
||||||
// setPaletteColor(...)
|
// setPaletteColor(...)
|
||||||
// getPaletteColor(colour)
|
// getPaletteColor(colour)
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
@ -3,25 +3,25 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -8,14 +8,14 @@ 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 var changedTrigger:SignalTrigger<Noise>;
|
||||||
|
|
||||||
private final text: Observable<String>;
|
private final text:Observable<String>;
|
||||||
private final bg:Color;
|
private final bg:Color;
|
||||||
private final fg:Color;
|
private final fg:Color;
|
||||||
|
|
||||||
public function new(text: Observable<String>,?background: Color = Black,?textColor: Color = White) {
|
public function new(text:Observable<String>, ?background:Color = Black, ?textColor:Color = White) {
|
||||||
|
|
||||||
setupTrigger();
|
setupTrigger();
|
||||||
|
|
||||||
this.text = text;
|
this.text = text;
|
||||||
@ -32,13 +32,13 @@ class TextElement implements IElement {
|
|||||||
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});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class BuildInfo {
|
|||||||
/**
|
/**
|
||||||
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
|
||||||
@ -40,4 +40,3 @@ class BuildInfo {
|
|||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,6 @@ package util;
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user