Merge pull request #4 from F0Xde/runnables

Use reified parameter for `executeCatching`; allow exception handlers to be sync or async
This commit is contained in:
Jakob K
2020-10-18 17:16:26 +02:00
committed by GitHub
2 changed files with 61 additions and 23 deletions

View File

@@ -2,8 +2,6 @@
package net.axay.kspigot.runnables package net.axay.kspigot.runnables
import net.axay.kspigot.main.KSpigotMainInstance
import org.bukkit.Bukkit
import kotlin.reflect.KClass import kotlin.reflect.KClass
abstract class ChainedRunnablePart<T, R>( abstract class ChainedRunnablePart<T, R>(
@@ -14,15 +12,38 @@ abstract class ChainedRunnablePart<T, R>(
protected abstract fun invoke(data: T): R protected abstract fun invoke(data: T): R
/**
* Begins execution of this chained runnable.
*/
abstract fun execute() abstract fun execute()
abstract fun <E : Exception> executeCatching( /**
@Suppress("UNCHECKED_CAST") exceptionClass: KClass<E> = Exception::class as KClass<E>, * Begins execution of this chained runnable, catching any exception of
exceptionHandler: ((E) -> Unit)? = null * 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(
exceptionSync: Boolean = true,
noinline exceptionHandler: ((E) -> Unit)? = null
) {
executeCatchingImpl(E::class, exceptionSync, exceptionHandler)
}
/**
* Has to be public for use in inline function [executeCatching], not
* intended to be used directly.
*/
abstract fun <E : Exception> executeCatchingImpl(
exceptionClass: KClass<E>,
exceptionSync: Boolean,
exceptionHandler: ((E) -> Unit)?,
) )
protected fun start(data: T) { protected fun start(data: T) {
this.run { bukkitRun(sync) {
val result = invoke(data) val result = invoke(data)
next?.start(result) next?.start(result)
} }
@@ -31,30 +52,29 @@ abstract class ChainedRunnablePart<T, R>(
protected fun <E : Exception> startCatching( protected fun <E : Exception> startCatching(
data: T, data: T,
exceptionClass: KClass<E>, exceptionClass: KClass<E>,
exceptionHandler: ((E) -> Unit)? exceptionSync: Boolean,
exceptionHandler: ((E) -> Unit)?,
) { ) {
this.run { bukkitRun(sync) {
val result = try { val result = try {
invoke(data) invoke(data)
} catch (e: Exception) { } catch (e: Exception) {
if (exceptionClass.isInstance(e)) { if (exceptionClass.isInstance(e)) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
exceptionHandler?.invoke(e as E) if (sync == exceptionSync) {
null exceptionHandler?.invoke(e as E)
} else if (exceptionHandler != null) {
bukkitRun(exceptionSync) {
exceptionHandler.invoke(e as E)
}
}
return@bukkitRun
} else throw e } else throw e
} }
if (result != null) next?.startCatching(result, exceptionClass, exceptionSync, exceptionHandler)
next?.startCatching(result, exceptionClass, exceptionHandler)
} }
} }
private fun run(realRunnable: () -> Unit) {
if (sync)
Bukkit.getScheduler().runTask(KSpigotMainInstance, realRunnable)
else
Bukkit.getScheduler().runTaskAsynchronously(KSpigotMainInstance, realRunnable)
}
} }
class ChainedRunnablePartFirst<R>( class ChainedRunnablePartFirst<R>(
@@ -65,8 +85,11 @@ class ChainedRunnablePartFirst<R>(
override fun execute() override fun execute()
= start(Unit) = start(Unit)
override fun <E : Exception> executeCatching(exceptionClass: KClass<E>, exceptionHandler: ((E) -> Unit)?) override fun <E : Exception> executeCatchingImpl(
= startCatching(Unit, exceptionClass, exceptionHandler) exceptionClass: KClass<E>,
exceptionSync: Boolean,
exceptionHandler: ((E) -> Unit)?
) = startCatching(Unit, exceptionClass, exceptionSync, exceptionHandler)
override fun invoke(data: Unit) = runnable.invoke() override fun invoke(data: Unit) = runnable.invoke()
@@ -81,8 +104,11 @@ class ChainedRunnablePartThen<T, R>(
override fun execute() override fun execute()
= previous.execute() = previous.execute()
override fun <E : Exception> executeCatching(exceptionClass: KClass<E>, exceptionHandler: ((E) -> Unit)?) override fun <E : Exception> executeCatchingImpl(
= previous.executeCatching(exceptionClass, exceptionHandler) exceptionClass: KClass<E>,
exceptionSync: Boolean,
exceptionHandler: ((E) -> Unit)?
) = previous.executeCatchingImpl(exceptionClass, exceptionSync, exceptionHandler)
override fun invoke(data: T) = runnable.invoke(data) override fun invoke(data: T) = runnable.invoke(data)

View File

@@ -104,6 +104,18 @@ fun task(
} }
/**
* Executes the given [runnable] either
* sync or async (specified by the [sync] parameter).
*/
fun bukkitRun(sync: Boolean, runnable: () -> Unit) {
if (sync) {
sync(runnable)
} else {
async(runnable)
}
}
/** /**
* Starts a synchronous task. * Starts a synchronous task.
*/ */