Use reified type parameter for executeCatching; sync / async handlers
The unsafe cast before would throw an exception if any other generic parameter than `Exception` was used without passing the class reference explicitly. It can now also be specified whether the exception handler is to be executed sync or async, defaulting to sync.
This commit is contained in:
@@ -2,8 +2,6 @@
|
||||
|
||||
package net.axay.kspigot.runnables
|
||||
|
||||
import net.axay.kspigot.main.KSpigotMainInstance
|
||||
import org.bukkit.Bukkit
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
abstract class ChainedRunnablePart<T, R>(
|
||||
@@ -16,13 +14,33 @@ abstract class ChainedRunnablePart<T, R>(
|
||||
|
||||
abstract fun execute()
|
||||
|
||||
abstract fun <E : Exception> executeCatching(
|
||||
@Suppress("UNCHECKED_CAST") exceptionClass: KClass<E> = Exception::class as KClass<E>,
|
||||
exceptionHandler: ((E) -> Unit)? = null
|
||||
/**
|
||||
* Begins execution of this chained runnable, catching any exception of
|
||||
* type [E] and passing it to the optional [exceptionHandler].
|
||||
*
|
||||
* @param exceptionSync whether the exception handler should be executed
|
||||
* synchronously or asynchronously, defaults to `true` (Note that usage of
|
||||
* any Spigot API functions requires it to be sync)
|
||||
*/
|
||||
inline fun <reified E : Exception> executeCatching(
|
||||
noinline exceptionHandler: ((E) -> Unit)? = null,
|
||||
exceptionSync: Boolean = true
|
||||
) {
|
||||
executeCatchingImpl(E::class, exceptionHandler, exceptionSync)
|
||||
}
|
||||
|
||||
/**
|
||||
* Has to be public for use in inline function [executeCatching], not
|
||||
* intended to be used directly.
|
||||
*/
|
||||
abstract fun <E : Exception> executeCatchingImpl(
|
||||
exceptionClass: KClass<E>,
|
||||
exceptionHandler: ((E) -> Unit)?,
|
||||
exceptionSync: Boolean
|
||||
)
|
||||
|
||||
protected fun start(data: T) {
|
||||
this.run {
|
||||
runTask(sync) {
|
||||
val result = invoke(data)
|
||||
next?.start(result)
|
||||
}
|
||||
@@ -31,30 +49,28 @@ abstract class ChainedRunnablePart<T, R>(
|
||||
protected fun <E : Exception> startCatching(
|
||||
data: T,
|
||||
exceptionClass: KClass<E>,
|
||||
exceptionHandler: ((E) -> Unit)?
|
||||
exceptionHandler: ((E) -> Unit)?,
|
||||
exceptionSync: Boolean
|
||||
) {
|
||||
this.run {
|
||||
runTask(sync) {
|
||||
val result = try {
|
||||
invoke(data)
|
||||
} catch (e: Exception) {
|
||||
if (exceptionClass.isInstance(e)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
exceptionHandler?.invoke(e as E)
|
||||
null
|
||||
if (sync == exceptionSync) {
|
||||
exceptionHandler?.invoke(e as E)
|
||||
} else if (exceptionHandler != null) {
|
||||
runTask(exceptionSync) {
|
||||
exceptionHandler.invoke(e as E)
|
||||
}
|
||||
}
|
||||
return@runTask
|
||||
} else throw e
|
||||
}
|
||||
if (result != null)
|
||||
next?.startCatching(result, exceptionClass, exceptionHandler)
|
||||
next?.startCatching(result, exceptionClass, exceptionHandler, exceptionSync)
|
||||
}
|
||||
}
|
||||
|
||||
private fun run(realRunnable: () -> Unit) {
|
||||
if (sync)
|
||||
Bukkit.getScheduler().runTask(KSpigotMainInstance, realRunnable)
|
||||
else
|
||||
Bukkit.getScheduler().runTaskAsynchronously(KSpigotMainInstance, realRunnable)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ChainedRunnablePartFirst<R>(
|
||||
@@ -65,8 +81,11 @@ class ChainedRunnablePartFirst<R>(
|
||||
override fun execute()
|
||||
= start(Unit)
|
||||
|
||||
override fun <E : Exception> executeCatching(exceptionClass: KClass<E>, exceptionHandler: ((E) -> Unit)?)
|
||||
= startCatching(Unit, exceptionClass, exceptionHandler)
|
||||
override fun <E : Exception> executeCatchingImpl(
|
||||
exceptionClass: KClass<E>, exceptionHandler: ((E) -> Unit)?,
|
||||
exceptionSync: Boolean
|
||||
) =
|
||||
startCatching(Unit, exceptionClass, exceptionHandler, exceptionSync)
|
||||
|
||||
override fun invoke(data: Unit) = runnable.invoke()
|
||||
|
||||
@@ -81,8 +100,11 @@ class ChainedRunnablePartThen<T, R>(
|
||||
override fun execute()
|
||||
= previous.execute()
|
||||
|
||||
override fun <E : Exception> executeCatching(exceptionClass: KClass<E>, exceptionHandler: ((E) -> Unit)?)
|
||||
= previous.executeCatching(exceptionClass, exceptionHandler)
|
||||
override fun <E : Exception> executeCatchingImpl(
|
||||
exceptionClass: KClass<E>, exceptionHandler: ((E) -> Unit)?,
|
||||
exceptionSync: Boolean
|
||||
) =
|
||||
previous.executeCatchingImpl(exceptionClass, exceptionHandler, exceptionSync)
|
||||
|
||||
override fun invoke(data: T) = runnable.invoke(data)
|
||||
|
||||
|
@@ -104,6 +104,14 @@ fun task(
|
||||
|
||||
}
|
||||
|
||||
fun runTask(sync: Boolean, runnable: () -> Unit) {
|
||||
if (sync) {
|
||||
sync(runnable)
|
||||
} else {
|
||||
async(runnable)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a synchronous task.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user