moved kernel events to new lib

This commit is contained in:
Djeeberjr 2022-02-21 15:17:38 +01:00
parent 1d2d4d88f8
commit 71deddc86a
9 changed files with 225 additions and 101 deletions

7
src/kernel/ButtonType.hx Normal file
View File

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

View File

@ -1,7 +1,10 @@
package kernel; package kernel;
import util.Vec.Vec2;
import haxe.Exception;
using tink.CoreApi;
import cc.OS; import cc.OS;
import util.EventBus;
using lua.Table; using lua.Table;
@ -11,38 +14,193 @@ using lua.Table;
class KernelEvents{ class KernelEvents{
public static var instance:KernelEvents; public static var instance:KernelEvents;
@:allow(kernel.Init) public final onAlarm: Signal<Int>;
private function new () {} public final onChar: Signal<String>;
public final onDisk: Signal<String>;
public final onDiskEject: Signal<String>;
public final onHttpCheck: Signal<{url:String,success:Bool,failReason:Any}>;
public final onHttpFailure: Signal<{url:String,failReason:String,handle:Any}>;
public final onHttpSuccess: Signal<{url:String,handle:Any}>;
public final onKey: Signal<{keyCode: Int,isHeld:Bool}>;
public final onKeyUp: Signal<Int>;
public final onModemMessage: Signal<{addr: String,channel:Int, replyChannel:Int,message:Dynamic,distance:Int}>;
public final onMonitorResize: Signal<String>;
public final onMonitorTouch: Signal<{addr:String,pos: Vec2<Int>}>;
public final onMouseClick: Signal<{button:ButtonType,pos: Vec2<Int>}>;
public final onMouseDrag: Signal<{button:ButtonType,pos: Vec2<Int>}>;
public final onMouseScroll: Signal<{dir:Int,pos: Vec2<Int>}>;
public final onMouseUp: Signal<{button:ButtonType,pos: Vec2<Int>}>;
public final onPaste: Signal<String>;
public final onPeripheral: Signal<String>;
public final onPeripheralDetach: Signal<String>;
public final onRednetMessage: Signal<{sender:Int,message:Any,protocol:Any}>;
public final onRedstone: Signal<Noise>;
public final onSpeakerAudioEmpty: Signal<String>;
public final onTaskComplete: Signal<{id:Int,success:Bool,failedReason:String}>;
public final onTermResize: Signal<Noise>;
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 var eventBus: util.EventBus<Array<Dynamic>> = new EventBus(); private final onAlarmTrigger: SignalTrigger<Int> = Signal.trigger();
private final onCharTrigger: SignalTrigger<String> = Signal.trigger();
private final onDiskTrigger: 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 onHttpFailureTrigger: SignalTrigger<{url:String,failReason: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 onKeyUpTrigger: SignalTrigger<Int> = Signal.trigger();
private final onModemMessageTrigger: SignalTrigger<{addr: String,channel:Int, replyChannel:Int,message:Dynamic,distance:Int}> = Signal.trigger();
private final onMonitorResizeTrigger: SignalTrigger<String> = Signal.trigger();
private final onMonitorTouchTrigger: SignalTrigger<{addr:String,pos: Vec2<Int>}> = Signal.trigger();
private final onMouseClickTrigger: SignalTrigger<{button:ButtonType,pos: Vec2<Int>}> = Signal.trigger();
private final onMouseDragTrigger: SignalTrigger<{button:ButtonType,pos: Vec2<Int>}> = Signal.trigger();
private final onMouseScrollTrigger: SignalTrigger<{dir:Int,pos: Vec2<Int>}> = Signal.trigger();
private final onMouseUpTrigger: SignalTrigger<{button:ButtonType,pos: Vec2<Int>}> = Signal.trigger();
private final onPasteTrigger: SignalTrigger<String> = Signal.trigger();
private final onPeripheralTrigger: SignalTrigger<String> = Signal.trigger();
private final onPeripheralDetachTrigger: SignalTrigger<String> = Signal.trigger();
private final onRednetMessageTrigger: SignalTrigger<{sender:Int,message:Any,protocol:Any}> = Signal.trigger();
private final onRedstoneTrigger: SignalTrigger<Noise> = Signal.trigger();
private final onSpeakerAudioEmptyTrigger: SignalTrigger<String> = Signal.trigger();
private final onTaskCompleteTrigger: SignalTrigger<{id:Int,success:Bool,failedReason:String}> = Signal.trigger();
private final onTermResizeTrigger: SignalTrigger<Noise> = 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)
private function new () {
this.onAlarm = onAlarmTrigger.asSignal();
this.onChar = onCharTrigger.asSignal();
this.onDisk = onDiskTrigger.asSignal();
this.onDiskEject = onDiskEjectTrigger.asSignal();
this.onHttpCheck = onHttpCheckTrigger.asSignal();
this.onHttpFailure = onHttpFailureTrigger.asSignal();
this.onHttpSuccess = onHttpSuccessTrigger.asSignal();
this.onKey = onKeyTrigger.asSignal();
this.onKeyUp = onKeyUpTrigger.asSignal();
this.onModemMessage = onModemMessageTrigger.asSignal();
this.onMonitorResize = onMonitorResizeTrigger.asSignal();
this.onMonitorTouch = onMonitorTouchTrigger.asSignal();
this.onMouseClick = onMouseClickTrigger.asSignal();
this.onMouseDrag = onMouseDragTrigger.asSignal();
this.onMouseScroll = onMouseScrollTrigger.asSignal();
this.onMouseUp = onMouseUpTrigger.asSignal();
this.onPaste = onPasteTrigger.asSignal();
this.onPeripheral = onPeripheralTrigger.asSignal();
this.onPeripheralDetach = onPeripheralDetachTrigger.asSignal();
this.onRednetMessage = onRednetMessageTrigger.asSignal();
this.onRedstone = onRedstoneTrigger.asSignal();
this.onSpeakerAudioEmpty = onSpeakerAudioEmptyTrigger.asSignal();
this.onTaskComplete = onTaskCompleteTrigger.asSignal();
this.onTermResize = onTermResizeTrigger.asSignal();
this.onTerminate = onTerminateTrigger.asSignal();
this.onTimer = onTimerTrigger.asSignal();
this.onTurtleInventory = onTurtleInventoryTrigger.asSignal();
this.onWebsocketClose = onWebsocketCloseTrigger.asSignal();
this.onWebsocketFailure = onWebsocketFailureTrigger.asSignal();
this.onWebsocketMessage = onWebsocketMessageTrigger.asSignal();
this.onWebsocketSuccess = onWebsocketSuccessTrigger.asSignal();
}
/** /**
Start pulling events. Blocking. Start pulling events. Blocking.
**/ **/
public function startEventLoop() { public function startEventLoop() {
// Log.info("Starting event loop");
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];
if (eventName == "terminate"){ switch eventName {
return; case "alarm":
this.onAlarmTrigger.trigger(event[2]);
case "char":
this.onCharTrigger.trigger(event[2]);
case "disk":
this.onDiskTrigger.trigger(event[2]);
case "disk_eject":
this.onDiskEjectTrigger.trigger(event[2]);
case "http_check":
this.onHttpCheckTrigger.trigger({url: event[2],success: event[3],failReason: event[4]});
case "http_failure":
this.onHttpFailureTrigger.trigger({url: event[2],failReason: event[3],handle: event[4]});
case "http_success":
this.onHttpSuccessTrigger.trigger({url: event[2],handle: event[3]});
case "key":
this.onKeyTrigger.trigger({keyCode: event[2],isHeld: event[3]});
case "key_up":
this.onKeyUpTrigger.trigger(event[2]);
case "modem_message":
this.onModemMessageTrigger.trigger({addr: event[2],channel: event[3],replyChannel: event[4],message: event[5],distance: event[6]});
case "monitor_resize":
this.onMonitorResizeTrigger.trigger(event[2]);
case "monitor_touch":
this.onMonitorTouchTrigger.trigger({addr: event[2],pos:{x: (event[3]:Int) - 1,y: (event[4]:Int) - 1}});
case "mouse_click":
this.onMouseClickTrigger.trigger({button: ccButtonToEnum(event[2]),pos:{ x: (event[3]:Int) - 1,y: (event[4]:Int) - 1}});
case "mouse_drag":
this.onMouseDragTrigger.trigger({button: ccButtonToEnum(event[2]),pos:{x: (event[3]:Int) - 1,y: (event[4]:Int) - 1}});
case "mouse_scroll":
this.onMouseScrollTrigger.trigger({dir: event[2],pos:{x:(event[3]:Int) - 1,y: (event[4]:Int) - 1}});
case "mouse_up":
this.onMouseUpTrigger.trigger({button: ccButtonToEnum(event[2]),pos:{x: (event[3]:Int) - 1,y: (event[4]:Int) - 1}});
case "paste":
this.onPasteTrigger.trigger(event[2]);
case "peripheral":
this.onPeripheralTrigger.trigger(event[2]);
case "peripheral_detach":
this.onPeripheralDetachTrigger.trigger(event[2]);
case "rednet_message":
this.onRednetMessageTrigger.trigger({sender: event[2],message: event[3],protocol: event[4]});
case "redstone":
this.onRedstoneTrigger.trigger(null);
case "speaker_audio_empty":
this.onSpeakerAudioEmptyTrigger.trigger(event[2]);
case "task_complete":
this.onTaskCompleteTrigger.trigger({id: event[2],success: event[3],failedReason: event[4]});
case "term_resize":
this.onTermResizeTrigger.trigger(null);
case "terminate":
this.onTerminateTrigger.trigger(null);
case "timer":
this.onTimerTrigger.trigger(event[2]);
case "turtle_inventory":
this.onTurtleInventoryTrigger.trigger(null);
case "websocket_closed":
this.onWebsocketCloseTrigger.trigger(event[2]);
case "websocket_failure":
this.onWebsocketFailureTrigger.trigger({url: event[2],failReason: event[3]});
case "websocket_message":
this.onWebsocketMessageTrigger.trigger({url: event[2],message: event[3],isBinary: event[4]});
case "websocket_success":
this.onWebsocketSuccessTrigger.trigger({url: event[2],handle: event[3]});
default:
Log.error("Unknown cc event: " + eventName);
} }
eventBus.emit(eventName,event.toArray());
} }
} }
public function on(eventName:String, callback:Array<Dynamic> -> Void):EventBusListner { private static function ccButtonToEnum(button: Dynamic): ButtonType {
return eventBus.on(eventName,callback); switch button {
} case 1:
return Left;
public function once(eventName:String, callback:Array<Dynamic> -> Void):EventBusListner { case 2:
return eventBus.once(eventName,callback); return Middle;
} case 3:
return Right;
public function removeListner(id:EventBusListner) { default:
return eventBus.removeListner(id); throw new Exception("Invalid input");
}
} }
} }

View File

@ -4,6 +4,7 @@ import kernel.ui.WindowContext;
import kernel.ui.WindowManager; import kernel.ui.WindowManager;
import lib.TermWriteable; import lib.TermWriteable;
import lib.TermIO; import lib.TermIO;
import util.Debug;
/** /**
Log messages to specified output. Log messages to specified output.

View File

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

View File

@ -2,7 +2,6 @@ package kernel;
using tink.CoreApi; using tink.CoreApi;
import util.EventBus.EventBusListner;
import cc.OS; import cc.OS;
/** /**
@ -11,7 +10,7 @@ import cc.OS;
class Timer { class Timer {
private final timerID:Int; private final timerID:Int;
private final callback:Callback<Noise>; private final callback:Callback<Noise>;
private final timerListner:EventBusListner; private final timerLink:CallbackLink;
/** /**
Create new timer with timeout in seconds. Create new timer with timeout in seconds.
@ -20,10 +19,10 @@ class Timer {
timerID = OS.startTimer(timeout); timerID = OS.startTimer(timeout);
this.callback = callback; this.callback = callback;
timerListner = KernelEvents.instance.on("timer",(params)->{ timerLink = KernelEvents.instance.onTimer.handle(timerID ->{
if (params[1] == timerID){ if (this.timerID == timerID){
callback.invoke(null); callback.invoke(null);
KernelEvents.instance.removeListner(timerListner); timerLink.cancel();
} }
}); });
} }
@ -33,6 +32,6 @@ class Timer {
**/ **/
public function cancle() { public function cancle() {
OS.cancelTimer(timerID); OS.cancelTimer(timerID);
KernelEvents.instance.removeListner(timerListner); timerLink.cancel();
} }
} }

View File

@ -21,10 +21,18 @@ class Net{
@:allow(kernel.Init) @:allow(kernel.Init)
private function new () { private function new () {
KernelEvents.instance.on("modem_message",(params)->{ KernelEvents.instance.onModemMessage.handle(params ->{
var pack = Package.fromEvent(params); var pack: Package = {
handelIncomming(pack,params[1]); fromID: params.replyChannel,
toID: params.channel,
msgID: params.message.msgID,
type: params.message.type,
data: params.message.data,
};
handelIncomming(pack,params.addr);
}); });
allModems = Peripheral.instance.getModems(); allModems = Peripheral.instance.getModems();
open(); open();
discoverNeighbors(); discoverNeighbors();

View File

@ -24,8 +24,8 @@ class Screen implements TermWriteable{
this.nativ = nativePeripherals; this.nativ = nativePeripherals;
this.addr = addr; this.addr = addr;
KernelEvents.instance.on("monitor_resize",params -> { KernelEvents.instance.onMonitorResize.handle(addr -> {
if (params[1] == this.addr){ if (addr == this.addr){
onResizeTrigger.trigger(getSize()); onResizeTrigger.trigger(getSize());
} }
}); });

View File

@ -3,7 +3,7 @@ package kernel.ui;
using tink.CoreApi; using tink.CoreApi;
import util.Color; import util.Color;
import kernel.ui.WindowManager.ButtonType; import kernel.ButtonType;
import util.Vec.Vec2; import util.Vec.Vec2;
import lib.TermWriteable; import lib.TermWriteable;

View File

@ -2,91 +2,56 @@ package kernel.ui;
import lib.TermWriteable; import lib.TermWriteable;
import kernel.peripherals.Peripherals.Peripheral; import kernel.peripherals.Peripherals.Peripheral;
import haxe.Exception;
import util.Vec.Vec2;
enum ButtonType {
Left;
Middle;
Right;
}
class WindowManager { class WindowManager {
public static var instance:WindowManager; public static var instance:WindowManager;
@:allow(kernel.Init) @:allow(kernel.Init)
private function new() { private function new() {
KernelEvents.instance.on("key",params -> {
var keyCode: Int = params[1]; KernelEvents.instance.onKey.handle(params ->{
var isHeld: Bool = params[2];
if (currentMainContext != null){ if (currentMainContext != null){
currentMainContext.keyTrigger.trigger({keyCode: keyCode,isHeld: isHeld}); currentMainContext.keyTrigger.trigger(params);
} }
}); });
KernelEvents.instance.on("key_up",params -> { KernelEvents.instance.onKeyUp.handle(keyCode -> {
var keyCode: Int = params[1];
if (currentMainContext != null){ if (currentMainContext != null){
currentMainContext.keyUpTrigger.trigger(keyCode); currentMainContext.keyUpTrigger.trigger(keyCode);
} }
}); });
KernelEvents.instance.on("mouse_click",params -> { KernelEvents.instance.onMouseClick.handle(params ->{
var button: ButtonType = ccButtonToEnum(params[1]);
var clickPos: Vec2<Int> = {
x: (params[2]:Int) - 1,
y: (params[3]:Int) - 1
};
if (currentMainContext != null){ if (currentMainContext != null){
currentMainContext.clickTrigger.trigger({button: button,pos: clickPos}); currentMainContext.clickTrigger.trigger(params);
}
});
KernelEvents.instance.onMouseDrag.handle(params ->{
if (currentMainContext != null){
currentMainContext.mouseDragTrigger.trigger(params);
} }
}); });
KernelEvents.instance.on("mouse_drag",params -> { KernelEvents.instance.onMouseScroll.handle(params ->{
var button: ButtonType = ccButtonToEnum(params[1]);
var pos: Vec2<Int> = {
x: (params[2]:Int) - 1,
y: (params[3]:Int) - 1,
}
if (currentMainContext != null){ if (currentMainContext != null){
currentMainContext.mouseDragTrigger.trigger({button: button,pos: pos}); currentMainContext.mouseScrollTrigger.trigger(params);
} }
}); });
KernelEvents.instance.on("mouse_scroll",params -> { KernelEvents.instance.onMouseUp.handle(params ->{
var dir: Int = params[1];
var pos: Vec2<Int> = {
x: (params[2]:Int) - 1,
y: (params[3]:Int) - 1,
}
if (currentMainContext != null){ if (currentMainContext != null){
currentMainContext.mouseScrollTrigger.trigger({dir: dir,pos: pos}); currentMainContext.mouseUpTrigger.trigger(params);
} }
}); });
KernelEvents.instance.on("mouse_up",params -> { KernelEvents.instance.onPaste.handle(text->{
var button: ButtonType = ccButtonToEnum(params[1]);
var pos: Vec2<Int> = {
x: (params[2]:Int) - 1,
y: (params[2]:Int) - 1,
}
if (currentMainContext != null){
currentMainContext.mouseUpTrigger.trigger({button: button,pos: pos});
}
});
KernelEvents.instance.on("paste",params -> {
var text: String = params[1];
if (currentMainContext != null){ if (currentMainContext != null){
currentMainContext.pasteTrigger.trigger(text); currentMainContext.pasteTrigger.trigger(text);
} }
}); });
KernelEvents.instance.on("monitor_touch",array -> { KernelEvents.instance.onMonitorTouch.handle(params ->{
// TODO // TODO
}); });
} }
@ -137,18 +102,4 @@ class WindowManager {
context.setTarget(target); context.setTarget(target);
context.enable(); context.enable();
} }
}
private static function ccButtonToEnum(button: Int): ButtonType {
switch button {
case 1:
return Left;
case 2:
return Middle;
case 3:
return Right;
case _:
throw new Exception("Invalid input");
}
}
}