PendingTask.kt (3286B) - raw


      1 package me.rhunk.snapenhance.task
      2 
      3 
      4 enum class TaskType(
      5     val key: String
      6 ) {
      7     DOWNLOAD("download"),
      8     CHAT_ACTION("chat_action");
      9 
     10     companion object {
     11         fun fromKey(key: String): TaskType {
     12             return entries.find { it.key == key } ?: throw IllegalArgumentException("Invalid key $key")
     13         }
     14     }
     15 }
     16 
     17 enum class TaskStatus(
     18     val key: String
     19 ) {
     20     PENDING("pending"),
     21     RUNNING("running"),
     22     SUCCESS("success"),
     23     FAILURE("failure"),
     24     CANCELLED("cancelled");
     25 
     26     fun isFinalStage(): Boolean {
     27         return this == SUCCESS || this == FAILURE || this == CANCELLED
     28     }
     29 
     30     companion object {
     31         fun fromKey(key: String): TaskStatus {
     32             return entries.find { it.key == key } ?: throw IllegalArgumentException("Invalid key $key")
     33         }
     34     }
     35 }
     36 
     37 data class PendingTaskListener(
     38     val onSuccess: () -> Unit = {},
     39     val onCancel: () -> Unit = {},
     40     val onProgress: (label: String?, progress: Int) -> Unit = { _, _ -> },
     41     val onStateChange: (status: TaskStatus) -> Unit = {},
     42 )
     43 
     44 data class Task(
     45     val type: TaskType,
     46     val title: String,
     47     val author: String?,
     48     val hash: String
     49 ) {
     50     var changeListener: () -> Unit = {}
     51 
     52     var extra: String? = null
     53         set(value) {
     54             field = value
     55             changeListener()
     56         }
     57     var status: TaskStatus = TaskStatus.PENDING
     58         set(value) {
     59             field = value
     60             changeListener()
     61         }
     62 }
     63 
     64 class PendingTask(
     65     val taskId: Long,
     66     val task: Task
     67 ) {
     68     private val listeners = mutableListOf<PendingTaskListener>()
     69 
     70     fun addListener(listener: PendingTaskListener) {
     71         synchronized(listeners) { listeners.add(listener) }
     72     }
     73 
     74     fun removeListener(listener: PendingTaskListener) {
     75         synchronized(listeners) { listeners.remove(listener) }
     76     }
     77 
     78     var status
     79         get() = task.status;
     80         set(value) {
     81             task.status = value;
     82             synchronized(listeners) {
     83                 listeners.forEach { it.onStateChange(value) }
     84             }
     85         }
     86 
     87     var progressLabel: String? = null
     88         set(value) {
     89             field = value
     90             synchronized(listeners) {
     91                 listeners.forEach { it.onProgress(value, progress) }
     92             }
     93         }
     94 
     95     private var _progress = 0
     96         set(value) {
     97             assert(value in 0..100 || value == -1)
     98             field = value
     99         }
    100 
    101     var progress get() = _progress
    102         set(value) {
    103             _progress = value
    104             synchronized(listeners) {
    105                 listeners.forEach { it.onProgress(progressLabel, value) }
    106             }
    107         }
    108 
    109     fun updateProgress(label: String, progress: Int = -1) {
    110         _progress = progress.coerceIn(-1, 100)
    111         progressLabel = label
    112     }
    113 
    114     fun fail(reason: String) {
    115         status = TaskStatus.FAILURE
    116         synchronized(listeners) {
    117             listeners.forEach { it.onCancel() }
    118         }
    119         updateProgress(reason)
    120     }
    121 
    122     fun success() {
    123         status = TaskStatus.SUCCESS
    124         synchronized(listeners) {
    125             listeners.forEach { it.onSuccess() }
    126         }
    127     }
    128 
    129     fun cancel() {
    130         status = TaskStatus.CANCELLED
    131         synchronized(listeners) {
    132             listeners.forEach { it.onCancel() }
    133         }
    134     }
    135 }