diff options
author | Dico <dico.karssiens@gmail.com> | 2018-08-02 18:56:50 +0100 |
---|---|---|
committer | Dico <dico.karssiens@gmail.com> | 2018-08-02 18:56:50 +0100 |
commit | 5626ff565258f9a4f32c69afd9f29fb2d51a9d87 (patch) | |
tree | 9cec31ecbb770a3814f84255916c73094e7f7114 /src | |
parent | 0af2e615d3fa1d8509be46e14f99d40dc9cdb342 (diff) |
Force complete WorktimeLimiter tasks on shutdown, Improve parcel info string
Diffstat (limited to 'src')
3 files changed, 66 insertions, 15 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt b/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt index 3a74626..6d08d28 100644 --- a/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt +++ b/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt @@ -47,6 +47,7 @@ class ParcelsPlugin : JavaPlugin() { } override fun onDisable() { + worktimeLimiter.completeAllTasks() cmdDispatcher?.unregisterFromCommandMap() } diff --git a/src/main/kotlin/io/dico/parcels2/blockvisitor/WorktimeLimiter.kt b/src/main/kotlin/io/dico/parcels2/blockvisitor/WorktimeLimiter.kt index a18c63b..30eaabd 100644 --- a/src/main/kotlin/io/dico/parcels2/blockvisitor/WorktimeLimiter.kt +++ b/src/main/kotlin/io/dico/parcels2/blockvisitor/WorktimeLimiter.kt @@ -28,6 +28,11 @@ sealed class WorktimeLimiter { * Get a list of all workers */ abstract val workers: List<Worker> + + /** + * Attempts to complete any remaining tasks immediately, without suspension. + */ + abstract fun completeAllTasks() } interface Timed { @@ -91,8 +96,14 @@ interface WorkerScope : Timed { private interface WorkerContinuation : Worker, WorkerScope { /** - * Start or resume the execution of this worker - * returns true if the worker completed + * Start or resumes the execution of this worker + * and returns true if the worker completed + * + * [worktime] is the maximum amount of time, in milliseconds, + * that this job may run for until suspension. + * + * If [worktime] is not positive, the worker will complete + * without suspension and this method will always return true. */ fun resume(worktime: Long): Boolean } @@ -106,7 +117,7 @@ class TickWorktimeLimiter(private val plugin: ParcelsPlugin, var options: TickWo // The currently registered bukkit scheduler task private var bukkitTask: BukkitTask? = null // The workers. - private var _workers = LinkedList<WorkerContinuation>() + private val _workers = LinkedList<WorkerContinuation>() override val workers: List<Worker> = _workers override fun submit(task: TimeLimitedTask): Worker { @@ -143,6 +154,15 @@ class TickWorktimeLimiter(private val plugin: ParcelsPlugin, var options: TickWo } } + override fun completeAllTasks() { + _workers.forEach { + it.resume(-1) + } + _workers.clear() + bukkitTask?.cancel() + bukkitTask = null + } + } private class WorkerImpl(val functionHelper: FunctionHelper, @@ -168,6 +188,7 @@ private class WorkerImpl(val functionHelper: FunctionHelper, private var onCompleted: WorkerUpdateLister? = null private var continuation: Continuation<Unit>? = null private var nextSuspensionTime: Long = 0L + private var completeForcefully = false private fun initJob(job: Job) { this.job?.let { throw IllegalStateException() } @@ -202,7 +223,7 @@ private class WorkerImpl(val functionHelper: FunctionHelper, } override suspend fun markSuspensionPoint() { - if (System.currentTimeMillis() >= nextSuspensionTime) + if (System.currentTimeMillis() >= nextSuspensionTime && !completeForcefully) suspendCoroutineUninterceptedOrReturn { cont: Continuation<Unit> -> continuation = cont COROUTINE_SUSPENDED @@ -220,7 +241,11 @@ private class WorkerImpl(val functionHelper: FunctionHelper, } override fun resume(worktime: Long): Boolean { - nextSuspensionTime = currentTimeMillis() + worktime + if (worktime > 0) { + nextSuspensionTime = currentTimeMillis() + worktime + } else { + completeForcefully = true + } continuation?.let { continuation = null diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt index 576fc48..c3d7c22 100644 --- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt @@ -84,6 +84,15 @@ private object ParcelInfoStringComputer { val infoStringColor1 = Formatting.GREEN val infoStringColor2 = Formatting.AQUA + private inline fun StringBuilder.appendField(field: StringBuilder.() -> Unit, value: StringBuilder.() -> Unit) { + append(infoStringColor1) + field() + append(": ") + append(infoStringColor2) + value() + append(' ') + } + private inline fun StringBuilder.appendField(name: String, value: StringBuilder.() -> Unit) { append(infoStringColor1) append(name) @@ -93,6 +102,26 @@ private object ParcelInfoStringComputer { append(' ') } + private fun StringBuilder.appendAddedList(local: Map<UUID, AddedStatus>, global: Map<UUID, AddedStatus>, status: AddedStatus, fieldName: String) { + val globalSet = global.filterValues { it == status }.keys + val localList = local.filterValues { it == status }.keys.filter { it !in globalSet } + val stringList = globalSet.map(::getPlayerName).map { "(G)$it" } + localList.map(::getPlayerName) + if (stringList.isEmpty()) return + + appendField({ + append(fieldName) + append('(') + append(infoStringColor2) + append(stringList.size) + append(infoStringColor1) + append(')') + }) { + stringList.joinTo(this, + separator = infoStringColor1.toString() + ", " + infoStringColor2, + limit = 150) + } + } + operator fun getValue(parcel: Parcel, property: KProperty<*>): String = buildString { appendField("ID") { append(parcel.x) @@ -100,8 +129,8 @@ private object ParcelInfoStringComputer { append(parcel.z) } + val owner = parcel.owner appendField("Owner") { - val owner = parcel.owner if (owner == null) { append(infoStringColor1) append("none") @@ -114,15 +143,11 @@ private object ParcelInfoStringComputer { append('\n') - val allowedMap = parcel.addedMap.filterValues { it.isAllowed } - if (allowedMap.isNotEmpty()) appendField("Allowed") { - allowedMap.keys.map(::getPlayerName).joinTo(this) - } - - val bannedMap = parcel.addedMap.filterValues { it.isBanned } - if (bannedMap.isNotEmpty()) appendField("Banned") { - bannedMap.keys.map(::getPlayerName).joinTo(this) - } + val global = owner?.let { parcel.world.globalAddedData[owner].addedMap } ?: emptyMap() + val local = parcel.addedMap + appendAddedList(local, global, AddedStatus.ALLOWED, "Allowed") + append('\n') + appendAddedList(local, global, AddedStatus.BANNED, "Banned") if (!parcel.allowInteractInputs || !parcel.allowInteractInventory) { appendField("Options") { |