Files
KSpigot/src/main/kotlin/net/axay/kspigot/runnables/KSpigotRunnables.kt
bluefireoly dcdb817a7c Changed runTask to bukkitRun
Changed the runTask method to bukkitRun and added documentation
2020-10-18 16:53:10 +02:00

129 lines
3.7 KiB
Kotlin

@file:Suppress("unused")
package net.axay.kspigot.runnables
import net.axay.kspigot.main.KSpigotMainInstance
import org.bukkit.Bukkit
import org.bukkit.scheduler.BukkitRunnable
internal object KRunnableHolder : AutoCloseable {
/**
* [BukkitRunnable] for tracking the responsible runnable.
* [Pair] of callback for the endCallback code and [Boolean]
* for holding the information if the endCallback is safe
* or not.
*/
private val runnableEndCallbacks = HashMap<BukkitRunnable, Pair<() -> Unit, Boolean>>()
override fun close() {
runnableEndCallbacks.values.forEach { if (it.second) it.first.invoke() }
runnableEndCallbacks.clear()
}
fun add(runnable: BukkitRunnable, callback: () -> Unit, safe: Boolean)
= runnableEndCallbacks.put(runnable, Pair(callback, safe))
fun remove(runnable: BukkitRunnable)
= runnableEndCallbacks.remove(runnable)
fun activate(runnable: BukkitRunnable)
= runnableEndCallbacks.remove(runnable)?.first?.invoke()
}
abstract class KSpigotRunnable(
var counterUp: Long? = null,
var counterDownToOne: Long? = null,
var counterDownToZero: Long? = null
) : BukkitRunnable()
/**
* Starts a new BukkitRunnable.
*
* @param sync if the runnable should run sync (true) or async (false)
* @param howOften how many times the task should be executed - null for infinite execution
* @param delay the delay (in ticks) until the first execution of the task
* @param period at which interval (in ticks) the task should be repeated
* @param safe if the endCallback of the runnable should always be executed,
* even if the server shuts down or the runnable ends prematurely
* @param endCallback code that should always be executed when the runnable ends
* @param runnable the runnable which should be executed each repetition
*/
fun task(
sync: Boolean = true,
delay: Long = 0,
period: Long? = null,
howOften: Long? = null,
safe: Boolean = false,
endCallback: (() -> Unit)? = null,
runnable: ((KSpigotRunnable) -> Unit)? = null
) {
if (howOften != null && howOften == 0L) return
val bukkitRunnable = object : KSpigotRunnable() {
private var curCounter = 0L
override fun run() {
var ranOut = false
if (howOften != null) {
counterDownToOne = howOften - curCounter
counterDownToZero = counterDownToOne?.minus(1)
curCounter++
if (curCounter >= howOften)
ranOut = true
counterUp = curCounter
}
runnable?.invoke(this)
if (ranOut) cancel()
if (isCancelled) {
if (safe || ranOut)
KRunnableHolder.activate(this)
else
KRunnableHolder.remove(this)
}
}
}
if (endCallback != null) KRunnableHolder.add(bukkitRunnable, endCallback, safe)
if (sync)
bukkitRunnable.runTaskTimer(KSpigotMainInstance, delay, period ?: 20)
else
bukkitRunnable.runTaskTimerAsynchronously(KSpigotMainInstance, delay, period ?: 20)
}
/**
* 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.
*/
fun sync(runnable: () -> Unit)
= Bukkit.getScheduler().runTask(KSpigotMainInstance, runnable)
/**
* Starts an asynchronous task.
*/
fun async(runnable: () -> Unit)
= Bukkit.getScheduler().runTaskAsynchronously(KSpigotMainInstance, runnable)