diff --git a/src/dorkbox/network/Client.kt b/src/dorkbox/network/Client.kt index a05d10c4..e6d756cd 100644 --- a/src/dorkbox/network/Client.kt +++ b/src/dorkbox/network/Client.kt @@ -746,7 +746,7 @@ open class Client(config: Configuration = Configuration * * @see RemoteObject */ - suspend inline fun createObject(vararg objectParameters: Any?, noinline callback: suspend (Int, Iface) -> Unit) { + suspend inline fun createObject(vararg objectParameters: Any?, noinline callback: suspend Iface.() -> Unit) { // NOTE: It's not possible to have reified inside a virtual function // https://stackoverflow.com/questions/60037849/kotlin-reified-generic-in-virtual-function val kryoId = serialization.getKryoIdForRmiClient(Iface::class.java) @@ -776,7 +776,7 @@ open class Client(config: Configuration = Configuration * * @see RemoteObject */ - suspend inline fun createObject(noinline callback: suspend (Int, Iface) -> Unit) { + suspend inline fun createObject(noinline callback: suspend Iface.() -> Unit) { // NOTE: It's not possible to have reified inside a virtual function // https://stackoverflow.com/questions/60037849/kotlin-reified-generic-in-virtual-function val kryoId = serialization.getKryoIdForRmiClient(Iface::class.java) diff --git a/src/dorkbox/network/connection/Connection.kt b/src/dorkbox/network/connection/Connection.kt index fbe076b4..684fe3fe 100644 --- a/src/dorkbox/network/connection/Connection.kt +++ b/src/dorkbox/network/connection/Connection.kt @@ -648,8 +648,8 @@ open class Connection(connectionParameters: ConnectionParams<*>) { * * @see RemoteObject */ - suspend fun createObject(vararg objectParameters: Any?, callback: suspend (Int, Iface) -> Unit) { - val iFaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(Function2::class.java, callback.javaClass, 1) + suspend fun createObject(vararg objectParameters: Any?, callback: suspend Iface.() -> Unit) { + val iFaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(Function1::class.java, callback.javaClass, 0) val kryoId = endPoint.serialization.getKryoIdForRmiClient(iFaceClass) @Suppress("UNCHECKED_CAST") @@ -675,8 +675,8 @@ open class Connection(connectionParameters: ConnectionParams<*>) { * * @see RemoteObject */ - suspend fun createObject(callback: suspend (Int, Iface) -> Unit) { - val iFaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(Function2::class.java, callback.javaClass, 1) + suspend fun createObject(callback: suspend Iface.() -> Unit) { + val iFaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(Function1::class.java, callback.javaClass, 0) val kryoId = endPoint.serialization.getKryoIdForRmiClient(iFaceClass) rmiConnectionSupport.createRemoteObject(this, kryoId, null, callback) diff --git a/src/dorkbox/network/rmi/RmiManagerConnections.kt b/src/dorkbox/network/rmi/RmiManagerConnections.kt index 6035b1cc..10677792 100644 --- a/src/dorkbox/network/rmi/RmiManagerConnections.kt +++ b/src/dorkbox/network/rmi/RmiManagerConnections.kt @@ -74,7 +74,7 @@ internal class RmiManagerConnections(logger: KLogger, /** * on the "client" to create a connection-specific remote object (that exists on the server) */ - suspend fun createRemoteObject(connection: Connection, kryoId: Int, objectParameters: Array?, callback: suspend (Int, Iface) -> Unit) { + suspend fun createRemoteObject(connection: Connection, kryoId: Int, objectParameters: Array?, callback: suspend Iface.() -> Unit) { val callbackId = rmiGlobalSupport.registerCallback(callback) // There is no rmiID yet, because we haven't created it! diff --git a/src/dorkbox/network/rmi/RmiManagerGlobal.kt b/src/dorkbox/network/rmi/RmiManagerGlobal.kt index d7f58272..7012a7e7 100644 --- a/src/dorkbox/network/rmi/RmiManagerGlobal.kt +++ b/src/dorkbox/network/rmi/RmiManagerGlobal.kt @@ -18,12 +18,7 @@ package dorkbox.network.rmi import dorkbox.network.connection.Connection import dorkbox.network.connection.EndPoint import dorkbox.network.connection.ListenerManager -import dorkbox.network.rmi.messages.ConnectionObjectCreateRequest -import dorkbox.network.rmi.messages.ConnectionObjectCreateResponse -import dorkbox.network.rmi.messages.GlobalObjectCreateRequest -import dorkbox.network.rmi.messages.GlobalObjectCreateResponse -import dorkbox.network.rmi.messages.MethodRequest -import dorkbox.network.rmi.messages.MethodResponse +import dorkbox.network.rmi.messages.* import dorkbox.network.serialization.Serialization import dorkbox.util.classes.ClassHelper import kotlinx.coroutines.launch @@ -81,11 +76,11 @@ internal class RmiManagerGlobal(logger: KLogger, private val remoteObjectCreationCallbacks = RemoteObjectStorage(logger) - internal fun registerCallback(callback: suspend (Int, Iface) -> Unit): Int { + internal fun registerCallback(callback: suspend Iface.() -> Unit): Int { return remoteObjectCreationCallbacks.register(callback) } - private fun removeCallback(callbackId: Int): suspend (Int, Any) -> Unit { + private fun removeCallback(callbackId: Int): suspend Any.() -> Unit { // callback's area always correct, because we track them ourselves. return remoteObjectCreationCallbacks.remove(callbackId)!! } @@ -125,7 +120,7 @@ internal class RmiManagerGlobal(logger: KLogger, connection: CONNECTION, isGlobal: Boolean, rmiId: Int, - callback: suspend (Int, Any) -> Unit, + callback: suspend Any.() -> Unit, serialization: Serialization) { // we only create the proxy + execute the callback if the RMI id is valid! @@ -134,7 +129,7 @@ internal class RmiManagerGlobal(logger: KLogger, return } - val interfaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(RemoteObjectCallback::class.java, callback.javaClass, 1) + val interfaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(RemoteObjectCallback::class.java, callback.javaClass, 0) // create the client-side proxy object, if possible. This MUST be an object that is saved for the connection var proxyObject = connection.rmiConnectionSupport.getProxyObject(rmiId) @@ -147,7 +142,7 @@ internal class RmiManagerGlobal(logger: KLogger, // this should be executed on a NEW coroutine! endPoint.actionDispatch.launch { try { - callback(rmiId, proxyObject) + callback(proxyObject) } catch (e: Exception) { ListenerManager.cleanStackTrace(e) endPoint.listenerManager.notifyError(e) diff --git a/test/dorkboxTest/network/SerializationValidationTest.kt b/test/dorkboxTest/network/SerializationValidationTest.kt index d3220c3e..a79aebae 100644 --- a/test/dorkboxTest/network/SerializationValidationTest.kt +++ b/test/dorkboxTest/network/SerializationValidationTest.kt @@ -100,16 +100,16 @@ class SerializationValidationTest : BaseTest() { client.onConnect { connection -> connection.logger.error("Connected") - connection.createObject { rmiId, remoteObject -> + connection.createObject { connection.logger.error("Starting test") - remoteObject.setValue(43.21f) + setValue(43.21f) // Normal remote method call. - Assert.assertEquals(43.21f, remoteObject.other(), .0001f) + Assert.assertEquals(43.21f, other(), .0001f) // When a proxy object is sent, the other side receives its ACTUAL object (not a proxy of it), because // that is where that object actually exists. - connection.send(remoteObject) + connection.send(this) } } @@ -147,16 +147,16 @@ class SerializationValidationTest : BaseTest() { client.onConnect { connection -> connection.logger.error("Connected") - connection.createObject { rmiId, remoteObject -> + connection.createObject { connection.logger.error("Starting test") - remoteObject.setValue(43.21f) + setValue(43.21f) // Normal remote method call. - Assert.assertEquals(43.21f, remoteObject.other(), .0001f) + Assert.assertEquals(43.21f, other(), .0001f) // When a proxy object is sent, the other side receives its ACTUAL object (not a proxy of it), because // that is where that object actually exists. - connection.send(remoteObject) + connection.send(this) } } diff --git a/test/dorkboxTest/network/rmi/RmiNestedTest.kt b/test/dorkboxTest/network/rmi/RmiNestedTest.kt index 17b4b311..3bf0ee33 100644 --- a/test/dorkboxTest/network/rmi/RmiNestedTest.kt +++ b/test/dorkboxTest/network/rmi/RmiNestedTest.kt @@ -90,17 +90,17 @@ class RmiNestedTest : BaseTest() { client.onConnect { connection -> connection.logger.error("Connected") - connection.createObject { rmiId, remoteObject -> + connection.createObject { connection.logger.error("Starting test") - remoteObject.setValue(43.21f) + setValue(43.21f) // Normal remote method call. - Assert.assertEquals(43.21f, remoteObject.other(), .0001f) + Assert.assertEquals(43.21f, other(), .0001f) // Make a remote method call that returns another remote proxy object. // the "test" object exists in the REMOTE side, as does the "OtherObject" that is created. // here we have a proxy to both of them. - val otherObject: OtherObject = remoteObject.getOtherObject() + val otherObject: OtherObject = getOtherObject() // Normal remote method call on the second object. otherObject.setValue(12.34f) @@ -109,7 +109,7 @@ class RmiNestedTest : BaseTest() { // make sure the "local" object and the "remote" object have the same values - Assert.assertEquals(12.34f, remoteObject.getOtherValue(), .0001f) + Assert.assertEquals(12.34f, getOtherValue(), .0001f) // When a proxy object is sent, the other side receives its ACTUAL object (not a proxy of it), because @@ -157,17 +157,17 @@ class RmiNestedTest : BaseTest() { client.onConnect { connection -> connection.logger.error("Connected") - connection.createObject { rmiId, remoteObject -> + connection.createObject { connection.logger.error("Starting test") - remoteObject.setValue(43.21f) + setValue(43.21f) // Normal remote method call. - Assert.assertEquals(43.21f, remoteObject.other(), .0001f) + Assert.assertEquals(43.21f, other(), .0001f) // Make a remote method call that returns another remote proxy object. // the "test" object exists in the REMOTE side, as does the "OtherObject" that is created. // here we have a proxy to both of them. - val otherObject: OtherObject = remoteObject.getOtherObject() + val otherObject: OtherObject = getOtherObject() // Normal remote method call on the second object. otherObject.setValue(12.34f) @@ -176,7 +176,7 @@ class RmiNestedTest : BaseTest() { // make sure the "local" object and the "remote" object have the same values - Assert.assertEquals(12.34f, remoteObject.getOtherValue(), .0001f) + Assert.assertEquals(12.34f, getOtherValue(), .0001f) // When a proxy object is sent, the other side receives its ACTUAL object (not a proxy of it), because @@ -224,15 +224,15 @@ class RmiNestedTest : BaseTest() { client.onConnect { connection -> connection.logger.error("Connected") - connection.createObject { rmiId, remoteObject -> + connection.createObject { connection.logger.error("Starting test") - remoteObject.setOtherValue(43.21f) + setOtherValue(43.21f) // Normal remote method call. - Assert.assertEquals(43.21f, remoteObject.getOtherValue(), .0001f) + Assert.assertEquals(43.21f, getOtherValue(), .0001f) // real object - val otherObject: OtherObject = remoteObject.getOtherObject() + val otherObject: OtherObject = getOtherObject() // Normal remote method call on the second object. val value = otherObject.value() @@ -264,15 +264,15 @@ class RmiNestedTest : BaseTest() { server.onConnect { connection -> connection.logger.error("Connected") - connection.createObject { rmiId, remoteObject -> + connection.createObject { connection.logger.error("Starting test") - remoteObject.setOtherValue(43.21f) + setOtherValue(43.21f) // Normal remote method call. - Assert.assertEquals(43.21f, remoteObject.getOtherValue(), .0001f) + Assert.assertEquals(43.21f, getOtherValue(), .0001f) // real object - val otherObject: OtherObject = remoteObject.getOtherObject() + val otherObject: OtherObject = getOtherObject() // Normal remote method call on the second object. val value = otherObject.value() diff --git a/test/dorkboxTest/network/rmi/RmiSimpleTest.kt b/test/dorkboxTest/network/rmi/RmiSimpleTest.kt index be66ff65..b36de062 100644 --- a/test/dorkboxTest/network/rmi/RmiSimpleTest.kt +++ b/test/dorkboxTest/network/rmi/RmiSimpleTest.kt @@ -143,9 +143,9 @@ class RmiSimpleTest : BaseTest() { server.logger.error("Starting test for: Server -> Client") // NOTE: THIS IS BI-DIRECTIONAL! - connection.createObject(123) { rmiId, remoteObject -> + connection.createObject(123) { server.logger.error("Running test for: Server -> Client") - RmiCommonTest.runTests(connection, remoteObject, 123) + RmiCommonTest.runTests(connection, this, 123) server.logger.error("Done with test for: Server -> Client") } } @@ -160,9 +160,9 @@ class RmiSimpleTest : BaseTest() { addEndPoint(client) client.onConnect { connection -> - connection.createObject(23) { rmiId, remoteObject -> + connection.createObject(23) { client.logger.error("Running test for: Client -> Server") - RmiCommonTest.runTests(connection, remoteObject, 23) + RmiCommonTest.runTests(connection, this, 23) client.logger.error("Done with test for: Client -> Server") } } @@ -219,9 +219,9 @@ class RmiSimpleTest : BaseTest() { server.logger.error("Finished test for: Client -> Server") // normally this is in the 'connected', but we do it here, so that it's more linear and easier to debug - connection.createObject(4) { rmiId, remoteObject -> + connection.createObject(4) { server.logger.error("Running test for: Server -> Client") - RmiCommonTest.runTests(connection, remoteObject, 4) + RmiCommonTest.runTests(connection, this, 4) server.logger.error("Done with test for: Server -> Client") } } @@ -256,9 +256,9 @@ class RmiSimpleTest : BaseTest() { client.logger.error("Starting test for: Client -> Server") // this creates a GLOBAL object on the server (instead of a connection specific object) - client.createObject(44) { rmiId, remoteObject -> + client.createObject(44) { client.logger.error("Running test for: Client -> Server") - RmiCommonTest.runTests(client.connection, remoteObject, 44) + RmiCommonTest.runTests(client.connection, this, 44) client.logger.error("Done with test for: Client -> Server") } } diff --git a/test/dorkboxTest/network/rmi/multiJVM/TestClient.kt b/test/dorkboxTest/network/rmi/multiJVM/TestClient.kt index b6319bfe..6570f991 100644 --- a/test/dorkboxTest/network/rmi/multiJVM/TestClient.kt +++ b/test/dorkboxTest/network/rmi/multiJVM/TestClient.kt @@ -78,12 +78,12 @@ object TestClient { client.onConnect { connection -> connection.logger.error("Starting test for: Client -> Server") - connection.createObject(124123) { _, remoteObject -> - RmiCommonTest.runTests(connection, remoteObject, 124123) + connection.createObject(124123) { + RmiCommonTest.runTests(connection, this, 124123) connection.logger.error("DONE") // now send this remote object ACROSS the wire to the server (on the server, this is where the IMPLEMENTATION lives) - connection.send(remoteObject) + connection.send(this) client.close() }