diff --git a/.gitignore b/.gitignore index 5e430fe4..feb17f21 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ gradle/ .gradle/ logs/ gradle.properties +gradlew +gradlew.bat \ No newline at end of file diff --git a/src/main/kotlin/net/axay/kspigot/runnables/ChainableRunnables.kt b/src/main/kotlin/net/axay/kspigot/runnables/ChainableRunnables.kt index c1945cab..8bd8176b 100644 --- a/src/main/kotlin/net/axay/kspigot/runnables/ChainableRunnables.kt +++ b/src/main/kotlin/net/axay/kspigot/runnables/ChainableRunnables.kt @@ -4,6 +4,7 @@ package net.axay.kspigot.runnables import net.axay.kspigot.main.KSpigotMainInstance import org.bukkit.Bukkit +import kotlin.reflect.KClass abstract class ChainedRunnablePart( val sync: Boolean @@ -11,15 +12,43 @@ abstract class ChainedRunnablePart( var next: ChainedRunnablePart? = null - abstract fun execute() - protected abstract fun invoke(data: T): R + abstract fun execute() + + abstract fun executeCatching( + @Suppress("UNCHECKED_CAST") exceptionClass: KClass = Exception::class as KClass, + exceptionHandler: ((E) -> Unit)? = null, + ) + protected fun start(data: T) { - val realRunnable = Runnable { + this.run { val result = invoke(data) next?.start(result) } + } + + protected fun startCatching( + data: T, + exceptionClass: KClass, + exceptionHandler: ((E) -> Unit)? + ) { + this.run { + val result = try { + invoke(data) + } catch (e: Exception) { + if (exceptionClass.isInstance(e)) { + @Suppress("UNCHECKED_CAST") + exceptionHandler?.invoke(e as E) + null + } else throw e + } + if (result != null) + next?.startCatching(result, exceptionClass, exceptionHandler) + } + } + + private fun run(realRunnable: () -> Unit) { if (sync) Bukkit.getScheduler().runTask(KSpigotMainInstance, realRunnable) else @@ -33,7 +62,11 @@ class ChainedRunnablePartFirst( sync: Boolean ) : ChainedRunnablePart(sync) { - override fun execute() = start(Unit) + override fun execute() + = start(Unit) + + override fun executeCatching(exceptionClass: KClass, exceptionHandler: ((E) -> Unit)?) + = startCatching(Unit, exceptionClass, exceptionHandler) override fun invoke(data: Unit) = runnable.invoke() @@ -45,19 +78,24 @@ class ChainedRunnablePartThen( val previous: ChainedRunnablePart<*, T> ) : ChainedRunnablePart(sync) { - override fun execute() = previous.execute() + override fun execute() + = previous.execute() + + override fun executeCatching(exceptionClass: KClass, exceptionHandler: ((E) -> Unit)?) + = previous.executeCatching(exceptionClass, exceptionHandler) override fun invoke(data: T) = runnable.invoke(data) } // FIRST -fun firstDo(sync: Boolean, runnable: () -> R) = ChainedRunnablePartFirst(runnable, sync) +fun firstDo(sync: Boolean, runnable: () -> R) + = ChainedRunnablePartFirst(runnable, sync) fun firstSync(runnable: () -> R) = firstDo(true, runnable) fun firstAsync(runnable: () -> R) = firstDo(false, runnable) // THEN fun ChainedRunnablePart.thenDo(sync: Boolean, runnable: (R) -> U) - = ChainedRunnablePartThen(runnable, sync, this).apply { previous.next = this } + = ChainedRunnablePartThen(runnable, sync, this).apply { previous.next = this } fun ChainedRunnablePart.thenSync(runnable: (R) -> U) = thenDo(true, runnable) fun ChainedRunnablePart.thenAsync(runnable: (R) -> U) = thenDo(false, runnable) \ No newline at end of file