Archived
0

Add elapsed time to WorktimeLimiter, make /p clear more elaborate

This commit is contained in:
Dico Karssiens
2018-07-30 05:13:30 +01:00
parent dee994b992
commit 72c82371b1
2 changed files with 44 additions and 12 deletions

View File

@@ -35,35 +35,62 @@ interface WorktimeLimiter {
typealias TimeLimitedTask = suspend WorktimeLimiter.() -> Unit typealias TimeLimitedTask = suspend WorktimeLimiter.() -> Unit
interface JobData { interface JobData {
/**
* The coroutine associated with this task, if any
*/
val job: Job? val job: Job?
/**
* The time that elapsed since this task was dispatched, in milliseconds
*/
val elapsedTime: Long
/**
* true if this task has completed
*/
val isComplete: Boolean val isComplete: Boolean
/**
* A value indicating the progress of this task, in the range 0.0 <= progress <= 1.0
* with no guarantees to its accuracy. May be null.
*/
val progress: Double? val progress: Double?
/** /**
* Calls the given [block] whenever the progress is updated, * Calls the given [block] whenever the progress is updated,
* if [minInterval] milliseconds expired since the last call. * if [minInterval] milliseconds expired since the last call.
*
* The first call occurs after at least [minDelay] milliseconds in a likewise manner. * The first call occurs after at least [minDelay] milliseconds in a likewise manner.
* Repeated invocations of this method result in an [IllegalStateException] * Repeated invocations of this method result in an [IllegalStateException]
*
* if [asCompletionListener] is true, [onCompleted] is called with the same [block]
*/ */
fun onProgressUpdate(minDelay: Int, minInterval: Int, block: JobUpdateListener): JobData fun onProgressUpdate(minDelay: Int, minInterval: Int, asCompletionListener: Boolean = true, block: JobUpdateListener): JobData
val isUpdateBlockPresent: Boolean
/** /**
* Calls the given [block] when this job completes. * Calls the given [block] when this job completes, with the progress value 1.0.
* Repeated invocations of this method result in an [IllegalStateException]
*/ */
fun onCompleted(block: JobUpdateListener): JobData fun onCompleted(block: JobUpdateListener): JobData
} }
typealias JobUpdateListener = JobData.(Double) -> Unit typealias JobUpdateListener = JobData.(Double, Long) -> Unit
class JobDataImpl(val task: TimeLimitedTask) : JobData { class JobDataImpl(val task: TimeLimitedTask) : JobData {
override var job: Job? = null override var job: Job? = null
set(value) { set(value) {
field?.let { throw IllegalStateException() } field?.let { throw IllegalStateException() }
field = value!! field = value!!
value.invokeOnCompletion { onCompletedBlock?.invoke(this, 1.0) } startTimeOrElapsedTime = System.currentTimeMillis()
value.invokeOnCompletion {
startTimeOrElapsedTime = System.currentTimeMillis() - startTimeOrElapsedTime
onCompletedBlock?.invoke(this, 1.0, elapsedTime)
} }
}
// when running: startTime, else: total elapsed time
private var startTimeOrElapsedTime: Long = 0L
override val elapsedTime get() = job?.let { if (it.isCompleted) startTimeOrElapsedTime else System.currentTimeMillis() - startTimeOrElapsedTime } ?: 0L
var next: Continuation<Unit>? = null var next: Continuation<Unit>? = null
@@ -77,20 +104,20 @@ class JobDataImpl(val task: TimeLimitedTask) : JobData {
val progressUpdate = progressUpdateBlock ?: return val progressUpdate = progressUpdateBlock ?: return
val time = System.currentTimeMillis() val time = System.currentTimeMillis()
if (time > lastUpdateTime + progressUpdateInterval) { if (time > lastUpdateTime + progressUpdateInterval) {
progressUpdate(progress!!) progressUpdate(progress!!, elapsedTime)
lastUpdateTime = time lastUpdateTime = time
} }
} }
override val isUpdateBlockPresent get() = progressUpdateBlock != null
private var progressUpdateBlock: JobUpdateListener? = null private var progressUpdateBlock: JobUpdateListener? = null
private var progressUpdateInterval: Int = 0 private var progressUpdateInterval: Int = 0
private var lastUpdateTime: Long = 0L private var lastUpdateTime: Long = 0L
override fun onProgressUpdate(minDelay: Int, minInterval: Int, block: JobUpdateListener): JobDataImpl { override fun onProgressUpdate(minDelay: Int, minInterval: Int, asCompletionListener: Boolean, block: JobUpdateListener): JobDataImpl {
progressUpdateBlock?.let { throw IllegalStateException() } progressUpdateBlock?.let { throw IllegalStateException() }
progressUpdateBlock = block progressUpdateBlock = block
progressUpdateInterval = minInterval progressUpdateInterval = minInterval
lastUpdateTime = System.currentTimeMillis() + minDelay - minInterval lastUpdateTime = System.currentTimeMillis() + minDelay - minInterval
if (asCompletionListener) onCompleted(block)
return this return this
} }

View File

@@ -1,5 +1,6 @@
package io.dico.parcels2.command package io.dico.parcels2.command
import io.dico.dicore.command.EMessageType
import io.dico.dicore.command.ExecutionContext import io.dico.dicore.command.ExecutionContext
import io.dico.dicore.command.annotation.Cmd import io.dico.dicore.command.annotation.Cmd
import io.dico.dicore.command.annotation.Desc import io.dico.dicore.command.annotation.Desc
@@ -83,10 +84,14 @@ class CommandsGeneral(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
@Cmd("clear") @Cmd("clear")
@ParcelRequire(owner = true) @ParcelRequire(owner = true)
fun ParcelScope.cmdClear(player: Player, context: ExecutionContext) { fun ParcelScope.cmdClear(player: Player, context: ExecutionContext) {
val onProgressUpdate: JobUpdateListener = { progress -> context.sendMessage("[Clearing] Progress: %.06f%%".format(progress * 100)) } val onProgressUpdate: JobUpdateListener = { progress, elapsedTime ->
context.sendMessage("[Clearing] Progress: %.06f%%".format(progress * 100))
}
world.generator.clearParcel(parcel) world.generator.clearParcel(parcel)
.onProgressUpdate(1000, 1500, onProgressUpdate) .onProgressUpdate(5, 5) { progress, elapsedTime ->
.onCompleted(onProgressUpdate) context.sendMessage(EMessageType.INFORMATIVE, "Clear progress: %.06f%%, %.2fs elapsed"
.format(progress * 100, elapsedTime / 1000.0))
}
} }
} }