diff --git a/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeFrameBuffer.kt b/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeFrameBuffer.kt index 32cb20abc1..43121bea37 100644 --- a/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeFrameBuffer.kt +++ b/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeFrameBuffer.kt @@ -32,7 +32,7 @@ class KorgeFrameBuffer(val path: String) { val IDX_FRAME_ID = 2 val IDX_WIDTH = 3 val IDX_HEIGHT = 4 - val IDX_DATA = 5 + val IDX_DATA = 8 } fun setFrame(frame: IPCFrame) { diff --git a/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeIPC.kt b/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeIPC.kt index 0799307d01..1f0c568cb2 100644 --- a/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeIPC.kt +++ b/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeIPC.kt @@ -32,22 +32,29 @@ class KorgeIPC(val path: String = DEFAULT_PATH) : AutoCloseable { private val connectedSockets = LinkedHashSet() + var onConnect: ((socket: KorgeIPCSocket) -> Unit)? = null + var onClose: ((socket: KorgeIPCSocket) -> Unit)? = null var onEvent: ((socket: KorgeIPCSocket, e: IPCPacket) -> Unit)? = null val socket = KorgeIPCSocket.openOrListen(socketPath, object : KorgeIPCSocketListener { override fun onConnect(socket: KorgeIPCSocket) { + println("onConnect[$socketPath][$socket]") synchronized(connectedSockets) { connectedSockets += socket } + onConnect?.invoke(socket) } override fun onClose(socket: KorgeIPCSocket) { + println("onClose[$socketPath][$socket]") + onClose?.invoke(socket) synchronized(connectedSockets) { connectedSockets -= socket } } override fun onEvent(socket: KorgeIPCSocket, e: IPCPacket) { + println("onEvent[$socketPath][$socket]: $e") synchronized(_events) { _events += e } diff --git a/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeIPCSocket.kt b/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeIPCSocket.kt index 81608521c5..65eead063a 100644 --- a/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeIPCSocket.kt +++ b/korge-ipc/src/main/kotlin/korlibs/korge/ipc/KorgeIPCSocket.kt @@ -200,7 +200,7 @@ class IPCPacket( val RESPONSE_NODE_SET_PROP = 0x7803 fun write(socket: SocketChannel, packet: IPCPacket) { - val head = ByteBuffer.allocate(4 + 4 + (4 * 4) + packet.data.size) + val head = ByteBuffer.allocate(8 + packet.data.size) head.putInt(packet.type) head.putInt(packet.data.size) head.put(packet.data) @@ -209,7 +209,7 @@ class IPCPacket( } fun read(socket: SocketChannel): IPCPacket { - val head = ByteBuffer.allocate(4 + 4 + (4 * 4)) + val head = ByteBuffer.allocate(8) socket.read(head) head.flip() val type = head.int diff --git a/korge/src@jvm/korlibs/korge/IPCViewsCompleter.kt b/korge/src@jvm/korlibs/korge/IPCViewsCompleter.kt index 2283ce4e20..852b236d08 100644 --- a/korge/src@jvm/korlibs/korge/IPCViewsCompleter.kt +++ b/korge/src@jvm/korlibs/korge/IPCViewsCompleter.kt @@ -13,137 +13,135 @@ class IPCViewsCompleter : ViewsCompleter { override fun completeViews(views: Views) { val korgeIPC = System.getenv("KORGE_IPC") if (korgeIPC != null) { - val queue = ArrayDeque>() - val ipc = KorgeIPC(korgeIPC) val viewsNodeId = ViewsNodeId(views) views.onBeforeRender { - synchronized(queue) { - while (queue.isNotEmpty()) { - val e = ipc.tryReadEvent() ?: break - //if (e.timestamp < System.currentTimeMillis() - 100) continue - //if (e.timestamp < System.currentTimeMillis() - 100 && e.type != IPCOldEvent.RESIZE && e.type != IPCOldEvent.BRING_BACK && e.type != IPCOldEvent.BRING_FRONT) continue // @TODO: BRING_BACK/BRING_FRONT - - when (e.type) { - IPCPacket.KEY_DOWN, IPCPacket.KEY_UP -> { - val keyCode = e.buffer.getInt() - val char = e.buffer.getInt() - - views.gameWindow.dispatchKeyEvent( - type = when (e.type) { - IPCPacket.KEY_DOWN -> KeyEvent.Type.DOWN - IPCPacket.KEY_UP -> KeyEvent.Type.UP - else -> KeyEvent.Type.DOWN - }, - id = 0, - key = awtKeyCodeToKey(keyCode), - character = char.toChar(), - keyCode = keyCode, - str = null, - ) - } + while (true) { + val e = ipc.tryReadEvent() ?: break + + println("PROCESSING_PACKET: $e") + //if (e.timestamp < System.currentTimeMillis() - 100) continue + //if (e.timestamp < System.currentTimeMillis() - 100 && e.type != IPCOldEvent.RESIZE && e.type != IPCOldEvent.BRING_BACK && e.type != IPCOldEvent.BRING_FRONT) continue // @TODO: BRING_BACK/BRING_FRONT + + when (e.type) { + IPCPacket.KEY_DOWN, IPCPacket.KEY_UP -> { + val keyCode = e.buffer.getInt() + val char = e.buffer.getInt() + + views.gameWindow.dispatchKeyEvent( + type = when (e.type) { + IPCPacket.KEY_DOWN -> KeyEvent.Type.DOWN + IPCPacket.KEY_UP -> KeyEvent.Type.UP + else -> KeyEvent.Type.DOWN + }, + id = 0, + key = awtKeyCodeToKey(keyCode), + character = char.toChar(), + keyCode = keyCode, + str = null, + ) + } - IPCPacket.MOUSE_MOVE, IPCPacket.MOUSE_DOWN, IPCPacket.MOUSE_UP, IPCPacket.MOUSE_CLICK -> { - val x = e.buffer.getInt() - val y = e.buffer.getInt() - val button = e.buffer.getInt() - - views.gameWindow.dispatchMouseEvent( - id = 0, - type = when (e.type) { - IPCPacket.MOUSE_CLICK -> MouseEvent.Type.CLICK - IPCPacket.MOUSE_MOVE -> MouseEvent.Type.MOVE - IPCPacket.MOUSE_DOWN -> MouseEvent.Type.UP - IPCPacket.MOUSE_UP -> MouseEvent.Type.UP - else -> MouseEvent.Type.DOWN - }, x = x, y = y, - button = MouseButton[button] - ) - //println(e) - } + IPCPacket.MOUSE_MOVE, IPCPacket.MOUSE_DOWN, IPCPacket.MOUSE_UP, IPCPacket.MOUSE_CLICK -> { + val x = e.buffer.getInt() + val y = e.buffer.getInt() + val button = e.buffer.getInt() + + views.gameWindow.dispatchMouseEvent( + id = 0, + type = when (e.type) { + IPCPacket.MOUSE_CLICK -> MouseEvent.Type.CLICK + IPCPacket.MOUSE_MOVE -> MouseEvent.Type.MOVE + IPCPacket.MOUSE_DOWN -> MouseEvent.Type.UP + IPCPacket.MOUSE_UP -> MouseEvent.Type.UP + else -> MouseEvent.Type.DOWN + }, x = x, y = y, + button = MouseButton[button] + ) + //println(e) + } - IPCPacket.RESIZE -> { - val width = e.buffer.getInt() - val height = e.buffer.getInt() + IPCPacket.RESIZE -> { + val width = e.buffer.getInt() + val height = e.buffer.getInt() - val awtGameWindow = (views.gameWindow as? AwtGameWindow?) - if (awtGameWindow != null) { - awtGameWindow.frame.setSize(width, height) - } else { - views.resized(width, height) - } - // + val awtGameWindow = (views.gameWindow as? AwtGameWindow?) + if (awtGameWindow != null) { + awtGameWindow.frame.setSize(width, height) + } else { + views.resized(width, height) } + // + } - IPCPacket.BRING_BACK, IPCPacket.BRING_FRONT -> { - val awtGameWindow = (views.gameWindow as? AwtGameWindow?) - if (awtGameWindow != null) { - if (e.type == IPCPacket.BRING_BACK) { - awtGameWindow.frame.toBack() - } else { - awtGameWindow.frame.toFront() - } + IPCPacket.BRING_BACK, IPCPacket.BRING_FRONT -> { + val awtGameWindow = (views.gameWindow as? AwtGameWindow?) + if (awtGameWindow != null) { + if (e.type == IPCPacket.BRING_BACK) { + awtGameWindow.frame.toBack() + } else { + awtGameWindow.frame.toFront() } } + } - IPCPacket.REQUEST_NODE_CHILDREN -> { - val req = e.parseJson() - val reqNodeId = req.nodeId - val container = viewsNodeId.findById(reqNodeId) as? Container? - val nodeId = viewsNodeId.getId(container) - val parentNodeId = viewsNodeId.getId(container?.parent) - - e.socket.writePacket(IPCPacket.fromJson(IPCNodeChildrenResponse.ID, IPCNodeChildrenResponse(nodeId, parentNodeId, container?.children?.map { - IPCNodeInfo( - viewsNodeId.getId(it), - isContainer = it is Container, - it::class.qualifiedName ?: "View", - it.name ?: "" - ) - }))) - } - IPCPacket.REQUEST_NODE_PROPS -> { - val req = e.parseJson() - val reqNodeId = req.nodeId - val view = viewsNodeId.findById(reqNodeId) - val nodeId = viewsNodeId.getId(view) - val parentNodeId = viewsNodeId.getId(view?.parent) - val info = ViewPropsInfo[view] - val groups = info.groups - val groupsByFqname = groups.associateBy { it.clazz.qualifiedName ?: "" } - - e.socket.writePacket(IPCPacket.fromJson(IPCNodePropsResponse.ID, IPCNodePropsResponse(nodeId, parentNodeId,groupsByFqname.mapValues { - if (view == null) { - emptyList() - } else { - it.value.actionsAndProps.map { - IPCPropInfo( - it.kname, it.name, it.ktype.toString(), - if (it.ktype == Unit::class) null else kotlin.runCatching { it.get(view).toString() }.getOrNull() - ) - } + IPCPacket.REQUEST_NODE_CHILDREN -> { + val req = e.parseJson() + val reqNodeId = req.nodeId + val container = viewsNodeId.findById(reqNodeId) as? Container? + val nodeId = viewsNodeId.getId(container) + val parentNodeId = viewsNodeId.getId(container?.parent) + + e.socket.writePacket(IPCPacket.fromJson(IPCNodeChildrenResponse.ID, IPCNodeChildrenResponse(nodeId, parentNodeId, container?.children?.map { + IPCNodeInfo( + viewsNodeId.getId(it), + isContainer = it is Container, + it::class.qualifiedName ?: "View", + it.name ?: "" + ) + }))) + } + IPCPacket.REQUEST_NODE_PROPS -> { + val req = e.parseJson() + val reqNodeId = req.nodeId + val view = viewsNodeId.findById(reqNodeId) + val nodeId = viewsNodeId.getId(view) + val parentNodeId = viewsNodeId.getId(view?.parent) + val info = ViewPropsInfo[view] + val groups = info.groups + val groupsByFqname = groups.associateBy { it.clazz.qualifiedName ?: "" } + + e.socket.writePacket(IPCPacket.fromJson(IPCNodePropsResponse.ID, IPCNodePropsResponse(nodeId, parentNodeId,groupsByFqname.mapValues { + if (view == null) { + emptyList() + } else { + it.value.actionsAndProps.map { + IPCPropInfo( + it.kname, it.name, it.ktype.toString(), + if (it.ktype == Unit::class) null else kotlin.runCatching { it.get(view).toString() }.getOrNull() + ) } - }))) - } - - IPCPacket.REQUEST_NODE_SET_PROP -> { - val req = e.parseJson() - val reqNodeId = req.nodeId - val view = viewsNodeId.findById(reqNodeId) - val nodeId = viewsNodeId.getId(view) - val info = ViewPropsInfo[view] - val basePWithProperty = info.allPropsAndActionsByKName[req.callId] - if (view != null) { - basePWithProperty?.set(view, req.value) } - e.socket.writePacket(IPCPacket.fromJson(IPCPacketPropSetResponse.ID, IPCPacketPropSetResponse(nodeId, req.callId, if (view == null) null else basePWithProperty?.get(view)?.toString()))) - } + }))) + } - else -> { - println(e) + IPCPacket.REQUEST_NODE_SET_PROP -> { + val req = e.parseJson() + val reqNodeId = req.nodeId + val view = viewsNodeId.findById(reqNodeId) + val nodeId = viewsNodeId.getId(view) + val info = ViewPropsInfo[view] + val basePWithProperty = info.allPropsAndActionsByKName[req.callId] + if (view != null) { + basePWithProperty?.set(view, req.value) } + e.socket.writePacket(IPCPacket.fromJson(IPCPacketPropSetResponse.ID, IPCPacketPropSetResponse(nodeId, req.callId, if (view == null) null else basePWithProperty?.get(view)?.toString()))) + } + + else -> { + println(e) } } } @@ -161,6 +159,7 @@ class IPCViewsCompleter : ViewsCompleter { //val bmp = it.ag.readColor(it.currentFrameBuffer) //channel.trySend(bmp) ipc.setFrame(IPCFrame(System.currentTimeMillis().toInt(), fb.width, fb.height, IntArray(0), fbMem.sliceWithSize(0, nbytes).nioIntBuffer)) + //println("SENT_FRAME") } } }