diff --git a/src/kernel/ButtonType.hx b/src/kernel/ButtonType.hx new file mode 100644 index 0000000..bc72d98 --- /dev/null +++ b/src/kernel/ButtonType.hx @@ -0,0 +1,7 @@ +package kernel; + +enum ButtonType { + Left; + Middle; + Right; +} diff --git a/src/kernel/KernelEvents.hx b/src/kernel/KernelEvents.hx index 0b6e278..e95c033 100644 --- a/src/kernel/KernelEvents.hx +++ b/src/kernel/KernelEvents.hx @@ -1,7 +1,10 @@ package kernel; +import util.Vec.Vec2; +import haxe.Exception; +using tink.CoreApi; + import cc.OS; -import util.EventBus; using lua.Table; @@ -11,38 +14,193 @@ using lua.Table; class KernelEvents{ public static var instance:KernelEvents; - @:allow(kernel.Init) - private function new () {} + public final onAlarm: Signal; + public final onChar: Signal; + public final onDisk: Signal; + public final onDiskEject: Signal; + 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; + public final onModemMessage: Signal<{addr: String,channel:Int, replyChannel:Int,message:Dynamic,distance:Int}>; + public final onMonitorResize: Signal; + public final onMonitorTouch: Signal<{addr:String,pos: Vec2}>; + public final onMouseClick: Signal<{button:ButtonType,pos: Vec2}>; + public final onMouseDrag: Signal<{button:ButtonType,pos: Vec2}>; + public final onMouseScroll: Signal<{dir:Int,pos: Vec2}>; + public final onMouseUp: Signal<{button:ButtonType,pos: Vec2}>; + public final onPaste: Signal; + public final onPeripheral: Signal; + public final onPeripheralDetach: Signal; + public final onRednetMessage: Signal<{sender:Int,message:Any,protocol:Any}>; + public final onRedstone: Signal; + public final onSpeakerAudioEmpty: Signal; + public final onTaskComplete: Signal<{id:Int,success:Bool,failedReason:String}>; + public final onTermResize: Signal; + public final onTerminate: Signal; + public final onTimer: Signal; + public final onTurtleInventory: Signal; + public final onWebsocketClose: Signal; + 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> = new EventBus(); + private final onAlarmTrigger: SignalTrigger = Signal.trigger(); + private final onCharTrigger: SignalTrigger = Signal.trigger(); + private final onDiskTrigger: SignalTrigger = Signal.trigger(); + private final onDiskEjectTrigger: SignalTrigger = 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 = Signal.trigger(); + private final onModemMessageTrigger: SignalTrigger<{addr: String,channel:Int, replyChannel:Int,message:Dynamic,distance:Int}> = Signal.trigger(); + private final onMonitorResizeTrigger: SignalTrigger = Signal.trigger(); + private final onMonitorTouchTrigger: SignalTrigger<{addr:String,pos: Vec2}> = Signal.trigger(); + private final onMouseClickTrigger: SignalTrigger<{button:ButtonType,pos: Vec2}> = Signal.trigger(); + private final onMouseDragTrigger: SignalTrigger<{button:ButtonType,pos: Vec2}> = Signal.trigger(); + private final onMouseScrollTrigger: SignalTrigger<{dir:Int,pos: Vec2}> = Signal.trigger(); + private final onMouseUpTrigger: SignalTrigger<{button:ButtonType,pos: Vec2}> = Signal.trigger(); + private final onPasteTrigger: SignalTrigger = Signal.trigger(); + private final onPeripheralTrigger: SignalTrigger = Signal.trigger(); + private final onPeripheralDetachTrigger: SignalTrigger = Signal.trigger(); + private final onRednetMessageTrigger: SignalTrigger<{sender:Int,message:Any,protocol:Any}> = Signal.trigger(); + private final onRedstoneTrigger: SignalTrigger = Signal.trigger(); + private final onSpeakerAudioEmptyTrigger: SignalTrigger = Signal.trigger(); + private final onTaskCompleteTrigger: SignalTrigger<{id:Int,success:Bool,failedReason:String}> = Signal.trigger(); + private final onTermResizeTrigger: SignalTrigger = Signal.trigger(); + private final onTerminateTrigger: SignalTrigger = Signal.trigger(); + private final onTimerTrigger: SignalTrigger = Signal.trigger(); + private final onTurtleInventoryTrigger: SignalTrigger = Signal.trigger(); + private final onWebsocketCloseTrigger: SignalTrigger = 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. **/ public function startEventLoop() { - // Log.info("Starting event loop"); while (true){ var event:Table = OS.pullEventRaw(); var eventName:String = event[1]; - if (eventName == "terminate"){ - return; + switch eventName { + 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 -> Void):EventBusListner { - return eventBus.on(eventName,callback); - } - - public function once(eventName:String, callback:Array -> Void):EventBusListner { - return eventBus.once(eventName,callback); - } - - public function removeListner(id:EventBusListner) { - return eventBus.removeListner(id); + private static function ccButtonToEnum(button: Dynamic): ButtonType { + switch button { + case 1: + return Left; + case 2: + return Middle; + case 3: + return Right; + default: + throw new Exception("Invalid input"); + } } } diff --git a/src/kernel/Log.hx b/src/kernel/Log.hx index cccf2f6..45fab11 100644 --- a/src/kernel/Log.hx +++ b/src/kernel/Log.hx @@ -4,6 +4,7 @@ import kernel.ui.WindowContext; import kernel.ui.WindowManager; import lib.TermWriteable; import lib.TermIO; +import util.Debug; /** Log messages to specified output. diff --git a/src/kernel/MainTerm.hx b/src/kernel/MainTerm.hx index 4d8850f..edefa73 100644 --- a/src/kernel/MainTerm.hx +++ b/src/kernel/MainTerm.hx @@ -21,7 +21,7 @@ class MainTerm implements TermWriteable{ this.onResizeTrigger = Signal.trigger(); this.onResize = this.onResizeTrigger.asSignal(); - KernelEvents.instance.on("term_resize",params ->{ + KernelEvents.instance.onTermResize.handle(_ ->{ onResizeTrigger.trigger(getSize()); }); } diff --git a/src/kernel/Timer.hx b/src/kernel/Timer.hx index 39a26a3..2657382 100644 --- a/src/kernel/Timer.hx +++ b/src/kernel/Timer.hx @@ -2,7 +2,6 @@ package kernel; using tink.CoreApi; -import util.EventBus.EventBusListner; import cc.OS; /** @@ -11,7 +10,7 @@ import cc.OS; class Timer { private final timerID:Int; private final callback:Callback; - private final timerListner:EventBusListner; + private final timerLink:CallbackLink; /** Create new timer with timeout in seconds. @@ -20,10 +19,10 @@ class Timer { timerID = OS.startTimer(timeout); this.callback = callback; - timerListner = KernelEvents.instance.on("timer",(params)->{ - if (params[1] == timerID){ + timerLink = KernelEvents.instance.onTimer.handle(timerID ->{ + if (this.timerID == timerID){ callback.invoke(null); - KernelEvents.instance.removeListner(timerListner); + timerLink.cancel(); } }); } @@ -33,6 +32,6 @@ class Timer { **/ public function cancle() { OS.cancelTimer(timerID); - KernelEvents.instance.removeListner(timerListner); + timerLink.cancel(); } } diff --git a/src/kernel/net/Net.hx b/src/kernel/net/Net.hx index f9332e8..edc3768 100644 --- a/src/kernel/net/Net.hx +++ b/src/kernel/net/Net.hx @@ -21,10 +21,18 @@ class Net{ @:allow(kernel.Init) private function new () { - KernelEvents.instance.on("modem_message",(params)->{ - var pack = Package.fromEvent(params); - handelIncomming(pack,params[1]); + KernelEvents.instance.onModemMessage.handle(params ->{ + var pack: Package = { + 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(); open(); discoverNeighbors(); diff --git a/src/kernel/peripherals/Screen.hx b/src/kernel/peripherals/Screen.hx index 09734ad..fb682c0 100644 --- a/src/kernel/peripherals/Screen.hx +++ b/src/kernel/peripherals/Screen.hx @@ -24,8 +24,8 @@ class Screen implements TermWriteable{ this.nativ = nativePeripherals; this.addr = addr; - KernelEvents.instance.on("monitor_resize",params -> { - if (params[1] == this.addr){ + KernelEvents.instance.onMonitorResize.handle(addr -> { + if (addr == this.addr){ onResizeTrigger.trigger(getSize()); } }); diff --git a/src/kernel/ui/WindowContext.hx b/src/kernel/ui/WindowContext.hx index 8240929..ca3170c 100644 --- a/src/kernel/ui/WindowContext.hx +++ b/src/kernel/ui/WindowContext.hx @@ -3,7 +3,7 @@ package kernel.ui; using tink.CoreApi; import util.Color; -import kernel.ui.WindowManager.ButtonType; +import kernel.ButtonType; import util.Vec.Vec2; import lib.TermWriteable; diff --git a/src/kernel/ui/WindowManager.hx b/src/kernel/ui/WindowManager.hx index 0908a89..452359f 100644 --- a/src/kernel/ui/WindowManager.hx +++ b/src/kernel/ui/WindowManager.hx @@ -2,91 +2,56 @@ package kernel.ui; import lib.TermWriteable; import kernel.peripherals.Peripherals.Peripheral; -import haxe.Exception; -import util.Vec.Vec2; - -enum ButtonType { - Left; - Middle; - Right; -} class WindowManager { public static var instance:WindowManager; @:allow(kernel.Init) private function new() { - KernelEvents.instance.on("key",params -> { - var keyCode: Int = params[1]; - var isHeld: Bool = params[2]; + + KernelEvents.instance.onKey.handle(params ->{ if (currentMainContext != null){ - currentMainContext.keyTrigger.trigger({keyCode: keyCode,isHeld: isHeld}); + currentMainContext.keyTrigger.trigger(params); } }); - - KernelEvents.instance.on("key_up",params -> { - var keyCode: Int = params[1]; + + KernelEvents.instance.onKeyUp.handle(keyCode -> { if (currentMainContext != null){ currentMainContext.keyUpTrigger.trigger(keyCode); } }); - KernelEvents.instance.on("mouse_click",params -> { - var button: ButtonType = ccButtonToEnum(params[1]); - var clickPos: Vec2 = { - x: (params[2]:Int) - 1, - y: (params[3]:Int) - 1 - }; - + KernelEvents.instance.onMouseClick.handle(params ->{ 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 -> { - var button: ButtonType = ccButtonToEnum(params[1]); - var pos: Vec2 = { - x: (params[2]:Int) - 1, - y: (params[3]:Int) - 1, - } + KernelEvents.instance.onMouseScroll.handle(params ->{ if (currentMainContext != null){ - currentMainContext.mouseDragTrigger.trigger({button: button,pos: pos}); + currentMainContext.mouseScrollTrigger.trigger(params); } }); - KernelEvents.instance.on("mouse_scroll",params -> { - var dir: Int = params[1]; - var pos: Vec2 = { - x: (params[2]:Int) - 1, - y: (params[3]:Int) - 1, - } - + KernelEvents.instance.onMouseUp.handle(params ->{ if (currentMainContext != null){ - currentMainContext.mouseScrollTrigger.trigger({dir: dir,pos: pos}); + currentMainContext.mouseUpTrigger.trigger(params); } }); - KernelEvents.instance.on("mouse_up",params -> { - var button: ButtonType = ccButtonToEnum(params[1]); - var pos: Vec2 = { - 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]; - + KernelEvents.instance.onPaste.handle(text->{ if (currentMainContext != null){ currentMainContext.pasteTrigger.trigger(text); } }); - KernelEvents.instance.on("monitor_touch",array -> { + KernelEvents.instance.onMonitorTouch.handle(params ->{ // TODO }); } @@ -137,18 +102,4 @@ class WindowManager { context.setTarget(target); 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"); - } - } - -} \ No newline at end of file +}