Issue
The code below has several possible failures. For example, width
could be null, or r
could be false. In all cases, I should return a result.error()
or something like that.
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else if (call.method=="registerTexture") {
val entry: TextureRegistry.SurfaceTextureEntry = texture_registry.createSurfaceTexture();
val surfaceTexture = entry.surfaceTexture();
//TODO: return non-sucess when no width and height passed
val width: Int = call.argument("width")!!
val height: Int = call.argument("height")!!
surfaceTexture.setDefaultBufferSize(width, height)
val response = HashMap<String, Long>()
RendererPlugin.surfaceTextureMap.put(entry, surfaceTexture)
val r = RendererPlugin.registerSurfaceTextureNativeHandler(entry.id(), surfaceTexture)
if (!r) {
Log.d(LOG_TAG, "attention: failed result from registerSurfaceTextureNativeHandler")
}
response.put("textureId", entry.id())
result.success(response)
}
}
On Rust, I'd make all of this into a closure which results Result<(), Error>
and then execute the closure inside onMethodCall
and if I got an error, I'd return an error. Also, the closure would be full of calls ending with ?
so it automatically returns the error that has a From<>
implementation that converts to Error
.
How can I do this efficiently in Kotlin? Is there a way to make a closure and also easily return success or error in this closure, and then based on this result I call result.sucess
or result.error
?
Solution
I hope this helps you.
Pay attention: I assume that result.success()
accepts Any
because you return String
or HashMap
as a parameter, but kotlin.Result
doesn't have several generic success parameters. You can play with kotlin.Pair<A, B>
as the success type of kotlin.Result
:D
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
val finalResult: kotlin.Result<Any> = call.run {
if (method == "getPlatformVersion") kotlin.Result.success("Android ${android.os.Build.VERSION.RELEASE}")
else if (method == "registerTexture") {
val entry: TextureRegistry.SurfaceTextureEntry = texture_registry.createSurfaceTexture();
val surfaceTexture = entry.surfaceTexture();
val width = argument("width") ?: return@run kotlin.Result.failure(IllegalArgumentException("width is null"))
val height = argument("height") ?: return@run kotlin.Result.failure(IllegalArgumentException("height is null"))
surfaceTexture.setDefaultBufferSize(width, height)
val response = HashMap<String, Long>()
RendererPlugin.surfaceTextureMap.put(entry, surfaceTexture)
val r = RendererPlugin.registerSurfaceTextureNativeHandler(entry.id(), surfaceTexture)
if (!r) return@run kotlin.Result.failure(IllegalArgumentException("r is false"))
response.put("textureId", entry.id())
kotlin.Result.success(response)
}
else kotlin.Result.failure(IllegalStateException("undefined call.method"))
}
with (finalResult) {
onSuccess(result::success)
onFailure(result::fail)
}
}
Answered By - plplmax
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.