package kernel; import cc.HTTP.HTTPResponse; import lua.TableTools; import lua.Coroutine; import util.Vec.Vec2; import haxe.Exception; using tink.CoreApi; using lua.Table; /** Class for interacting with the native pullEvent system. **/ class KernelEvents { /** Depends on: (Nothing) **/ public static var instance:KernelEvents; 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:HTTPResponse}>; public final onHttpSuccess:Signal<{url:String, handle:HTTPResponse}>; 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 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:HTTPResponse}> = Signal.trigger(); private final onHttpSuccessTrigger:SignalTrigger<{url:String, handle:HTTPResponse}> = 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() { while (true) { var event:Table = pullEvents(); var eventName:String = event[1]; fireSignal(eventName,event); } } private function pullEvents():Table { return cast TableTools.pack(Coroutine.yield(null)); } private function fireSignal(eventName: String,event:Table ) { 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 event: $eventName'); } } 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"); } } }